记录一次帮策划写的基于VBA的数据转化工具

由于策划计算的表格结构和程序实际使用的数据表结构不一定一致,因此有时候经常需要做数据转化。把策划自己的表格转成程序需要的格式,然后再导入数据库。这次也是策划有个表,里面有多个字段分别表示多个属性,但是程序考虑到通用,不想一个属性增加一个字段,因此想用一个字段,然后采用JSON格式来表示所有属性。

因此,帮策划写了个VBA实现多个字段合并成JSON的。这个VBA可以通过Ctrl表格来配置:

源表名:策划表的名字

目标表名:程序表的名字

字段映射:程序表的字段名对应策划表的字段名。目前支持字段合并(即把策划表里面的多个字段使用JSON合并成程序表需要的一个字段)。字段映射的行数和程序表的字段数量一样。

Sub 按钮1_Click()SearchColumn = 1CTRL_TABLE_NAME = "Ctrl"TotalRow = CountRow(CTRL_TABLE_NAME)SOURCE_TABLE = GetValueByKey(CTRL_TABLE_NAME, "源表名", TotalRow, SearchColumn)TARGET_TABLE = GetValueByKey(CTRL_TABLE_NAME, "目标表名", TotalRow, SearchColumn)Dim srcFieldsArr() As StringfieldNum = 0Set dict = CreateObject("Scripting.Dictionary")'Set dict = CreateObject("Scripting.Dictionary")' 源表格总行数SrcTableRowCount = CountRow(SOURCE_TABLE)For Row = 1 To TotalRow        If Cells(Row, 1) = "字段映射" Then            fieldNum = fieldNum + 1            ReDim Preserve srcFieldsArr(fieldNum)                        srcFieldsArr(fieldNum) = Cells(Row, 2)                        totalColumn = CountColumn(CTRL_TABLE_NAME, Row)            Dim arr() As String '存放目标表格列            ReDim arr(1 To totalColumn - 2)            For i = 3 To totalColumn                arr(i - 2) = Cells(Row, i)            Next            dict.Add fieldNum, arr        End IfNext Row'源表格列名和索引的映射Set SrcRowNameToIndex = CreateObject("Scripting.Dictionary")For Column = 1 To CountColumn(SOURCE_TABLE, 1)    SrcRowNameToIndex.Add Worksheets(SOURCE_TABLE).Cells(1, Column).Value, ColumnNext Column' 处理数据For Row = 2 To SrcTableRowCount    For i = 1 To fieldNum            arr = dict(i)                If UBound(arr) = 1 Then            SrcColumnIndex = SrcRowNameToIndex(arr(1))            Worksheets(TARGET_TABLE).Cells(Row, i) = Worksheets(SOURCE_TABLE).Cells(Row, SrcColumnIndex)        Else            proStr = "{"            For j = 1 To UBound(arr)                SrcColumnIndex = SrcRowNameToIndex(arr(j))                proStr = proStr & """" & Worksheets(SOURCE_TABLE).Cells(1, SrcColumnIndex) & """" & ":" & Worksheets(SOURCE_TABLE).Cells(Row, SrcColumnIndex)                If j < UBound(arr) Then                    proStr = proStr & ", "                End If            Next            proStr = proStr & "}"                        Worksheets(TARGET_TABLE).Cells(Row, i) = proStr        End If    NextNext    End Sub' 根据传入参数索引单元格,然后返回它后面单元格的值Function GetValueByKey(ByVal Sheetname As String, Key As String, ByVal RowLimit As Integer, ByVal SearchColumn As Integer) As String    For Row = 1 To RowLimit        If Worksheets(Sheetname).Cells(Row, SearchColumn) = Key Then            GetValueByKey = Worksheets(Sheetname).Cells(Row, SearchColumn + 1)        End If    Next RowEnd Function' 计算行数,从第一行开始往下数,直到第N行第1列为空,则行数为N-1Function CountRow(ByVal Sheetname As String) As Integer    Count = 1    CountRow = 1    While Count > 0     If Worksheets(Sheetname).Cells(Count, 1) <> "" Then           CountRow = Count           Count = Count + 1     Else            Count = 0     End If    WendEnd Function' 计算某行的列数Function CountColumn(ByVal Sheetname As String, ByVal Row As Integer) As Integer    Count = 1    CountColumn = 1    While Count > 0     If Worksheets(Sheetname).Cells(Row, Count) <> "" Then           CountColumn = Count           Count = Count + 1     Else            Count = 0     End If    WendEnd Function' 字母列号转数字Function ColumnNumber(ByVal ColumnLetter As String) As Integer       If Len(ColumnLetter) > 1 Then           ColumnNumber = (Asc(Mid(ColumnLetter, 1, 1)) - 64) * 26 + (Asc(Mid(ColumnLetter, 2, 1)) - 64)       Else           ColumnNumber = Asc(ColumnLetter) - 64       End IfEnd Function

这个是控制页面

上面Ctrl表的配置表示:

把策划表Source里面的mechaId列的数据复制到程序表的mechaId列;

把策划表Source里面的quality列的数据复制到程序表的quality列;

把策划表的

hpwuliattackwulidefendnengliangattacknengliangdefendcritRateantiCritRatehitRatemissRategedangdjpojidjrecoverEnergyattackSpeedcritHarmRatedamageleixin

这些列采用JSON合并复制到程序表的properties列。

这个是策划的数据表

这个是程序的数据表(通过点击控制页的按钮生成的)

写这个包括查VBA的资料总共大概花了2个小时,不得不说,VBA的语法真不好看!

勇敢的冷静的理智的去接受失败,有时不但是必要的,而且是很有必要的。

记录一次帮策划写的基于VBA的数据转化工具

相关文章:

你感兴趣的文章:

标签云: