實(shí)際開(kāi)發(fā)過(guò)程中,策劃習(xí)慣使用 Excel 填寫(xiě)游戲數(shù)據(jù),而程序使用的配置數(shù)據(jù)一般是 xml,json,lua 或者某種自定義的 DSL (Domain Specific Language) 等,或是 scriptable 等二進(jìn)制文件,所以產(chǎn)生了一個(gè)把 Excel 里的數(shù)據(jù)轉(zhuǎn)換成程序所需要的 "導(dǎo)表" 的過(guò)程.
一般團(tuán)隊(duì)的導(dǎo)表工具都是程序?qū)懙?,有好的方面,也有壞的方?好的方面是: 程序會(huì)對(duì)比 MD5 碼來(lái)確定文件一致.壞的方面是: 要規(guī)定文件路徑,只能一次性轉(zhuǎn)換所有表格,或者選擇所需轉(zhuǎn)換表格時(shí)難用的 UI, 表格 sheet 名和表的某一行必須有特殊規(guī)定等.最大的問(wèn)題還是這個(gè)工具對(duì)策劃并不開(kāi)源,加上導(dǎo)表工具里還有上傳 SVN, 重啟服務(wù)器等一系列自動(dòng)化操作,出了錯(cuò)誤之后無(wú)法確定是配置數(shù)據(jù)問(wèn)題,還是工具問(wèn)題,網(wǎng)絡(luò)問(wèn)題,在這條管線里面,就有了巨大的甩鍋空間.
所以策劃要牢牢把握住這口鍋,出了錯(cuò)就是你配置的錯(cuò),誰(shuí)讓你離開(kāi)了 Excel 連游戲都不會(huì)做了呢? 下面以 json 格式舉例,講幾種策劃也能學(xué)會(huì)的方法,制作自己的導(dǎo)表工具.
題外話,非常不推薦直接把 Excel 導(dǎo)入進(jìn)數(shù)據(jù)庫(kù)的操作.
方法一: 手動(dòng)轉(zhuǎn)換
最簡(jiǎn)單的就是復(fù)制粘貼手動(dòng)存成 json, 對(duì),就這樣干,因?yàn)槌绦蛞木褪莻€(gè) json 文件而已.沙塔斯城里的商人說(shuō)過(guò)一句話:
"你要戰(zhàn)爭(zhēng),我就給你戰(zhàn)爭(zhēng),水果販."
我們先分析下 json 格式一般是什么樣的,以下面這段為例:
可以看出,整個(gè)文件是用大括號(hào) {} 包裹起來(lái),左邊引號(hào)里的是 key, 右邊是對(duì)應(yīng)的 value. Value 有多種類(lèi)型: 是個(gè)數(shù)字的 / 用引號(hào)圈起來(lái)的 / 用大括號(hào)圈起來(lái)的 / 和用中括號(hào)圈起來(lái)的,那么我們只要弄成這樣就好了.
下面看 excel 表格里面的格式一般是這樣的:
第一行是字段名,下面是字段的值,一般用 id 作為數(shù)據(jù)庫(kù)里面的 key, 或者還有自動(dòng)生成的 uid, 增加一行用作標(biāo)記改字段的類(lèi)型等,大差不差的內(nèi)容.我們需要的就是把每一行都通過(guò) "字段: 值,字段: 值..." 的形式連接起來(lái),然后用個(gè)大括號(hào)來(lái)包裹即可.
我們后面加一列,通過(guò) Excel 的函數(shù),來(lái)獲取我們需要的數(shù)據(jù).給策劃新人們一個(gè)建議,就是函數(shù)要一步一步地寫(xiě),哪怕一共有十幾步,每一步的結(jié)果都放在一列里,確認(rèn)結(jié)果正確后,再拼接到一起,寫(xiě)一個(gè)超長(zhǎng)的函數(shù) (不能超過(guò) 255 個(gè)字符), 然后刪掉中間的步驟,云淡風(fēng)輕地對(duì)旁邊的人說(shuō):"不就是這樣簡(jiǎn)單嗎?"
第一步:
=INDEX($A$1:$F$1,COLUMN(A2))
index 函數(shù)用來(lái)獲得字段名,第一個(gè)參數(shù) $A$1:$F$1 是第一行需要的字段范圍,注意加上 $ 符號(hào),快捷鍵是 F4...(自己搜索吧,有一種教人 ' 這是冰箱 ' 的感覺(jué)), 第二個(gè)參數(shù)是當(dāng)前值所在的列號(hào),如果前面還有空行的話,這里要減去相應(yīng)的數(shù)量.
橫著一拖,豎著一拖,看到了需要的內(nèi)容是我們要的 key.
接著連接冒號(hào)和每一行的值:
=INDEX($A$1:$F$1,COLUMN(A2))&":"&A2
然后使用 textJoin 函數(shù),連接在一起,外面接上大括號(hào)就好了.
="{"&TEXTJOIN(",",TRUE,G2:L2)&"}"
有人問(wèn)了,所需要的 json 的 key 有引號(hào)的啊,要怎么辦?
最簡(jiǎn)單的就是字段名字就給他加上引號(hào)!
到這里主體部分就完成了,每一條 {} 大括號(hào)里面的,都是個(gè) json 的對(duì)象.對(duì)象之間用 [] 包裹起來(lái),就是一個(gè) json 的列表,或者還有 {} 包裹組成 kv 對(duì),那么就只需要在把拼接的內(nèi)容再次按照要求拼接就好了.
有人可能會(huì)問(wèn)了,最重要的云淡風(fēng)輕,怎么還沒(méi)講? 這么多輔助列,明明是手忙腳亂啊? 怎么能寫(xiě)到一個(gè)函數(shù)里面啊?
別急,這里我們要用到數(shù)組公式.直接上公式:
{="{"&TEXTJOIN(",",TRUE,INDEX($A$1:$F$1,COLUMN(A2:F2))&":"&A2:F2)&"}"}
只要把值從一個(gè)格子 A2, 變成一個(gè)范圍 A2:F2, 然后按 CTRL+SHITF+ENTER 輸入數(shù)組公式就好了.(數(shù)組公式最外面的大括號(hào)不是打字打上去的...)
至此,終于可以云淡風(fēng)輕了,因?yàn)橐话愠绦蛟骋膊惶珪?huì)用 Excel, 這樣就顯得你很專(zhuān)業(yè)了.
方法二: 自定義函數(shù)加載項(xiàng)
上面的例子中,有的字段的值是數(shù)組,用 [] 中括號(hào)引起來(lái),例如
"keywords":["小豬","小肚","小雞"]
或者自定義的類(lèi)似 lambda 表達(dá)式的東西
scripts:(Count(Unit))=100&Count(Wonder)=3IsDead(Bob)
這個(gè)時(shí)候?yàn)榱瞬邉澨畋矸奖?,可能每一列都有特殊的拼接方法,我們?cè)诘诙欣锩鎸?xiě)上值的類(lèi)型,示例如下:
這種會(huì)有很多特殊的,定制的內(nèi)容,例如看到 lambda 的時(shí)候,賦值給一個(gè)臨時(shí)變量名,例如
lambda1=(Count(Unit))=100&Count(Wonder)=3IsDead(Bob)
array 字段為了策劃填寫(xiě)方便,用逗號(hào)分割起來(lái),生成的時(shí)候還是要分別加上引號(hào),并用中括號(hào)括起來(lái)
"keyword":["小豬","小肚","小雞"]
面對(duì)這些定制化的需求,直接用 Excel 里的函數(shù),就捉襟見(jiàn)肘了.那么我們來(lái)自己寫(xiě)一個(gè),高度定制化的函數(shù)。
打開(kāi) Visual Basic 的 IDE,如果你的 Excel 不顯示開(kāi)發(fā)工具選項(xiàng)卡,則需要在自定義功能區(qū)里勾選一下。
插入一個(gè)模塊,寫(xiě)入下列代碼:
Function textToJson(ByVal s As Variant) Dim myKey,myValue Dim valueType Dim output '將單元格范圍作為選中范圍 Dim mr As Range Set mr = s '讀取第一行的key,和當(dāng)前的value組成一對(duì) For Each i In mr If Not IsEmpty(i) And i <> 0 Then '通過(guò)第二行的類(lèi)型來(lái)處理對(duì)應(yīng)的值 valueType = Cells(2, i.Column) myKey = Cells(1, i.Column) myValue = i.value Select Case valueType 'lambda把key特殊處理,加一個(gè)用行號(hào)作為序列號(hào)的變量 Case "lambda" myKey = "lambda" & i.Row - 2 output = output & myKey & "=" & myValue & "," 'array把值特殊處理,將逗號(hào)分隔的字符串放在一個(gè)數(shù)組里 Case "array" temp = "" tempString = Split(i.value, ",") For Each k In tempString temp = temp & Chr(34) & k & Chr(34) & "," Next k temp = Left(temp, Len(temp) - 1) temp = "[" & temp & "]" myValue = temp output = output & myKey & ":" & myValue & "," '情況不做處理 Case Else output = output & myKey & ":" & myValue & "," End Select End If Next i '最后拼接一下 If IsError(output) Or Len(output) <= 1 Then textToJson = "" Else output = Left(output, Len(output) - 1) textToJson = "{" & output & "}" End If End Function
這樣我們定義了 textToJson()這個(gè)函數(shù),在最后一列里面輸入 = textToJson (A3:F3) 即可轉(zhuǎn)換。
如果其他表格也想使用該函數(shù),但是不想轉(zhuǎn)換成 xlsm 這帶宏的格式,怎么辦?
我們可以把這個(gè)文件另存為 xlam,作為加載宏,給其他表格使用。
其他表格使用時(shí),通過(guò)開(kāi)發(fā)工具》Excel 加載項(xiàng)》瀏覽 找到該文件,即可使用 textToJson 這個(gè)自定義函數(shù)。
方法三:VBA
上面既然已經(jīng)用了自定義函數(shù),還要另存為等手動(dòng)操作,那么不如使用 VBA 直接導(dǎo)出。寫(xiě)法基本一樣,只不過(guò)創(chuàng)建了一個(gè) json 文件作為 object 來(lái)承載導(dǎo)出的內(nèi)容。注意,如果報(bào)出找不到對(duì)象的錯(cuò)誤的話,那么可以去人民公園試試。
Sub toJson() Dim i, j, k As Integer Dim myString, output As String Dim myRange As Range Dim myArr() Dim myTitle() Dim WriteStream As Object Set MyFile = CreateObject("Scripting.FileSystemObject").OpenTextFile("D:\testjson.json", 8, True) myString = "" output = "" i = 0 j = 0 k = 0 Set myRange = Selection myArr = myRange ReDim myTitle(20) For k = 0 To myRange.Columns.Count - 1 myTitle(k) = myArr(1, k + 1) Next k For i = 2 To myRange.Rows.Count output = output & "{" For j = 1 To myRange.Columns.Count If myTitle(j - 1) = "truth" Then myString = Trim(myArr(i, j)) output = output & Chr(34) & myTitle(j - 1) & Chr(34) & ":" & LCase(myString) & "," ElseIf myTitle(j - 1) = "tag" Or myTitle(j - 1) = "falseWord" Then myString = Trim(myArr(i, j)) output = output & Chr(34) & myTitle(j - 1) & Chr(34) & ":[" & mySubString(myString) & "]," ElseIf myTitle(j - 1) = "difficulty" Then myString = Trim(myArr(i, j)) output = output & Chr(34) & myTitle(j - 1) & Chr(34) & ":" & myString & "," Else myString = Trim(myArr(i, j)) output = output & Chr(34) & myTitle(j - 1) & Chr(34) & ":" & Chr(34) & myString & Chr(34) & "," End If Next j output = Mid(output, 1, Len(output) - 1) output = output & "}," & Chr(10) Next i output = Mid(output, 1, Len(output) - 2) ' Set WriteStream = CreateObject("ADODB.Stream") ' ' With WriteString' .Type = 2' .Charset = "UTF-8"' ' End With MyFile.WriteLine (output) MyFile.Close Set MyFile = Nothing MsgBox "成功??!" 'UserForm1.TextBox1.Text = output 'UserForm1.Show End Sub
以上代碼是我們做過(guò)的一個(gè)答題游戲的例子,超過(guò)幾萬(wàn)條有趣的問(wèn)題。配置表可以稍微露一下:
方法四:其他
大家可能會(huì)問(wèn)了,這一個(gè)一個(gè)表格的導(dǎo)出,太麻煩了,能不能一起導(dǎo)出多張?很多公司用 VBA 寫(xiě)過(guò)導(dǎo)出多張表格的工具,我也寫(xiě)過(guò),但因?yàn)?VBA 先天的弱勢(shì),速度極慢,還容易卡死。
這里推薦用 python 去寫(xiě),速度快 100 倍??梢杂?openpyxl 庫(kù),至于如何寫(xiě),可以參考上一篇文章:世界杯到了,寫(xiě)個(gè)爬蟲(chóng)獲取球員數(shù)據(jù)吧
因?yàn)楹芎?jiǎn)單,在此不再贅述了,可以作為初學(xué) python 的某種練習(xí)。還可以通過(guò) pandas 模塊把 excel 讀成字典對(duì)象,然后直接存進(jìn) mySQL 或者 mongodb,根本不需要導(dǎo)表這個(gè)中間過(guò)程了。
本文來(lái)自微信公眾號(hào):千猴馬的游戲設(shè)計(jì)之道 (ID:baima21th),作者:千兩
廣告聲明:文內(nèi)含有的對(duì)外跳轉(zhuǎn)鏈接(包括不限于超鏈接、二維碼、口令等形式),用于傳遞更多信息,節(jié)省甄選時(shí)間,結(jié)果僅供參考,IT之家所有文章均包含本聲明。