forked from zhyongquan/DBC2Excel
/
Excel2DBC.vb
270 lines (233 loc) · 8.38 KB
/
Excel2DBC.vb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'If you see this comment, you have already cracked this tool.I hope this code will help you.
'Submit issue if you have problem.
'Author: zhyongquan
'Email: zhyongquan@gmail.com
'GitHub: https://github.com/zhyongquan/Excel2DBC
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Option Explicit
'clms of Msg and Sig
Const vClmMsg As Integer = 6
Const vClmSig As Integer = 22
Private Enum eCLM
eMessage = 1
eID
eDLC
eTxMethod
eCycleTime
eMsgComment
'Signal Attr
eSignal '7
eMultipGrp
eStartbit
eLength
eByteOrder
eValueType
eInitialValue
eFactor
eOffset
eMinimum
eMaximum
eUnit
eValueTable
eSigComment
eConflict
eFileIndex '22
End Enum
Dim dicMsgB, dicSigB As Scripting.Dictionary
' (k-id,v-idx), (id-sig,idx)
Private Sub excel2dbc_Click()
Application.DisplayAlerts = False
On Error Resume Next
Dim i, j, k, node_count, message_count, signal_count As Integer
Dim Filename, arr
Dim nodes As String
Dim message, id, dlc, cycle_time, tx
Dim line, signal, byte_order, value_type, initial_value, value_table, comment, rx As String
Dim initial_value_list, value_table_list, cycle_time_list, comment_list As String
Dim str, text As String
Dim fso As New FileSystemObject
Dim starttime, endtime As Date
Dim elapsed As Double
Dim dbc_type As String
Dim vtmpMulti As String
Filename = Application.GetSaveAsFilename(fileFilter:="DBC Files (*.dbc), *.dbc")
If Filename = False Then
Exit Sub
End If
Set dicMsgB = New Scripting.Dictionary
Set dicSigB = New Scripting.Dictionary
dbc_type = ActiveSheet.Cells(1, 2)
starttime = Now
endtime = starttime
Open Filename For Output As 1#
If dbc_type <> "J1939" Then
Print #1, Sheet4.Cells(1, 2)
Else
Print #1, Sheet5.Cells(1, 2)
End If
Print #1, vbLf
i = vClmSig + 1
nodes = ""
While Len(ActiveSheet.Cells(2, i)) > 0
node_count = node_count + 1
nodes = nodes & " " & ActiveSheet.Cells(2, i)
i = i + 1
Wend
Print #1, "BU_:" & nodes
i = 3
message_count = 0
signal_count = 0
While Len(ActiveSheet.Cells(i, vClmMsg + 1)) > 0 'exist Signal
If Len(ActiveSheet.Cells(i, eMessage)) > 0 Then
'read Message Attr
If NOT dicMsgB.Exists(CStr(ActiveSheet.Cells(i, eID))) Then
dicMsgB.Add CStr(ActiveSheet.Cells(i, eID)), dicMsgB.Count + 1
message_count = message_count + 1
message = ActiveSheet.Cells(i, 1)
id = Hex2Dec(ActiveSheet.Cells(i, eID))
If dbc_type <> "Standard" Then
id = id + 2147483648#
End If
dlc = ActiveSheet.Cells(i, eDLC)
tx = ""
For j = 1 To node_count
If ActiveSheet.Cells(i, j + vClmSig) = "T" Then
tx = ActiveSheet.Cells(2, j + vClmSig)
Exit For
End If
Next j
If tx = "" Then
tx = "Vector__XXX"
End If
'writ Message head
Print #1, vbLf
Print #1, "BO_ " & id & " " & ActiveSheet.Cells(i, eMessage) & ": " & ActiveSheet.Cells(i, eDLC) & " " & tx
'CycleTime
If Len(ActiveSheet.Cells(i, eCycleTime) > 0) Then
cycle_time = ActiveSheet.Cells(i, eCycleTime) + 0
'cycle_time_list = cycle_time_list & "BA_ " & """GenMsgILSupport"" BO_ " & id & " " & 1 & ";" & vbLf
cycle_time_list = cycle_time_list & "BA_ " & """GenMsgSendType"" BO_ " & id & " " & 0 & ";" & vbLf
cycle_time_list = cycle_time_list & "BA_ " & """GenMsgCycleTime"" BO_ " & id & " " & cycle_time & ";" & vbLf
End If
End If
End If
'Signal set
signal_count = signal_count + 1
signal = ActiveSheet.Cells(i, eSignal)
If ActiveSheet.Cells(i, eByteOrder) = "MSB" Then
byte_order = "0"
Else
byte_order = "1"
End If
If ActiveSheet.Cells(i, eValueType) = "Unsigned" Then
value_type = "+"
Else
value_type = "-"
End If
rx = ""
For j = 1 To node_count
If ActiveSheet.Cells(i, j + vClmSig) = "R" Then
rx = rx & ActiveSheet.Cells(2, j + vClmSig) & ","
End If
Next j
If rx = "" Then
rx = " Vector__XXX"
Else
rx = Mid(rx, 1, Len(rx) - 1)
End If
'Multi
If ActiveSheet.Cells(i, eMultipGrp) <> "-" Then
vtmpMulti = " " & ActiveSheet.Cells(i, eMultipGrp)
Else
vtmpMulti = ""
End If
Print #1, " SG_ " & ActiveSheet.Cells(i, eSignal) & vtmpMulti & " : " & ActiveSheet.Cells(i, eStartbit) & "|" & ActiveSheet.Cells(i, eLength) & "@" & byte_order & value_type & _
" (" & Num2Str(ActiveSheet.Cells(i, eFactor)) & "," & Num2Str(ActiveSheet.Cells(i, eOffset)) & ") " & "[" & Num2Str(ActiveSheet.Cells(i, eMinimum)) & "|" & Num2Str(ActiveSheet.Cells(i, eMaximum)) & "] " & _
"""" & ActiveSheet.Cells(i, eUnit) & """ " & rx
If Len(ActiveSheet.Cells(i, eInitialValue)) > 0 And Len(ActiveSheet.Cells(i, eMessage)) > 0 And ActiveSheet.Cells(i, eFactor) <> 0 Then
initial_value = (ActiveSheet.Cells(i, eInitialValue) - ActiveSheet.Cells(i, eOffset)) / ActiveSheet.Cells(i, eFactor)
initial_value_list = initial_value_list & "BA_ ""GenSigStartValue"" SG_ " & id & " " & signal & " " & initial_value & ";" & vbLf
End If
If Len(ActiveSheet.Cells(i, eValueTable)) > 0 Then
arr = Split(ActiveSheet.Cells(i, eValueTable), vbLf)
value_table = ""
For j = UBound(arr) To 0 Step -1
k = InStr(arr(j), "=")
value_table = value_table & Hex2Dec(Mid(arr(j), 1, k - 1)) & " """ & Mid(arr(j), k + 1, Len(arr(j)) - k - 1) & """ "
Next j
value_table_list = value_table_list & "VAL_ " & id & " " & signal & " " & value_table & ";" & vbLf
End If
If Len(ActiveSheet.Cells(i, eSigComment)) > 0 Then
comment = ActiveSheet.Cells(i, eSigComment)
comment_list = comment_list & "CM_ SG_ " & id & " " & signal & " """ & comment & """;" & vbLf
End If
i = i + 1
Wend
Print #1, vbLf
Print #1, comment_list
If dbc_type <> "J1939" Then
Print #1, Sheet4.Cells(2, 2)
Print #1, Sheet4.Cells(3, 2)
Else
Print #1, Sheet5.Cells(2, 2)
Print #1, Sheet5.Cells(3, 2)
End If
Print #1, "BA_ ""DBName"" """ & fso.GetBaseName(Filename) + """;" + vbLf
Print #1, cycle_time_list
Print #1, initial_value_list
Print #1, value_table_list
Close #1
str = "DBC File= " + fso.GetFileName(Filename) + vbLf
str = str + "ECU Nodes Count= " + CStr(node_count) + vbLf
str = str + "Messages Count= " + CStr(message_count) + vbLf
str = str + "Signals Count= " + CStr(signal_count)
'ActiveSheet.Cells(1, 5) = str
Set fso = Nothing
MsgBox "Finish, " + GetElapsedTime(starttime, "elapsed time")
End Sub
Private Function Num2Str(ByVal num) As String
Dim str As String
str = CStr(num)
If Len(str) > 0 And Mid(str, 1, 1) = "." Then
str = "0" & str
ElseIf Len(str) > 0 And Mid(str, 1, 2) = "-." Then
str = "-0." & Mid(str, 3, Len(str) - 2)
End If
Num2Str = str
End Function
Private Function GetElapsedTime(ByVal starttime As Date, ByVal step As String) As String
Dim text As String
Dim elapsed As Double
Dim endtime As Date
endtime = Now
elapsed = endtime - starttime
text = step + ": " + Format(elapsed * 3600 * 24, "#0") + "s"
GetElapsedTime = text
End Function
Function Hex2Dec(h)
h = Mid(h, 3, Len(h) - 2)
Dim L As Long: L = Len(h)
If L < 16 Then ' CDec results in Overflow error for hex numbers above 16 ^ 8
Hex2Dec = CDec("&h0" & h)
If Hex2Dec < 0 Then Hex2Dec = Hex2Dec + 4294967296# ' 2 ^ 32
ElseIf L < 25 Then
Hex2Dec = Hex2Dec(Left$(h, L - 9)) * 68719476736# + CDec("&h" & Right$(h, 9)) ' 16 ^ 9 = 68719476736
End If
End Function
Private Function Col_Letter(ByVal lngCol As Long) As String
Dim vArr
vArr = Split(Cells(1, lngCol).Address(True, False), "$")
Col_Letter = vArr(0)
End Function
Sub excel2dbc(control As IRibbonControl)
Dim ret As Integer
Dim hint As String
ActiveWindow.ScrollColumn = 6
Range(Col_Letter(eConflict) + "2").AutoFilter Field:=21, Criteria1:=Array("Conflict"), Operator:=xlFilterValues
hint = "请先确认表格中已无冲突信号!!!" & vbLf & "已无冲突信号???" & vbLf
ret = MsgBox(hint, vbYesNo, "注意!!!")
If ret = vbYes Then
excel2dbc_Click
End If
End Sub