我公司VBA的一个常见用法是根据Excel表格中输入的信息生成源代码。鉴于VBA的本地字符串操作,执行此操作的代码编写起来很繁琐,而且不易读取。
一个简单的例子(这些变得更复杂)是:
Print #fileIdentifier, SSpace(9) & "update_" & print_string & "[" & CStr(j) & "] <= 1'b0;"
Print #fileIdentifier, SSpace(9) & print_string & "_ack_meta" & "[" & CStr(j) & "] <= 1'b0;"
Print #fileIdentifier, SSpace(9) & print_string & "_ack_sync" & "[" & CStr(j) & "] <= 1'b0;"
我正在寻找一个VBA解决方案,允许我使用&#34;文本模板&#34;来指定它,所以定义一个看起来像这样的文本
update_@name@[@bit@] <= 1'b0; @name@_ack_meta[@bit@] <= 1'b0; @name@_ack_sync[@bit@] <= 1'b0;
并进行函数/方法调用,传递@ name @和@ bit @的值,将@ name @和@ bit @的所有实例替换为相应的值。
答案 0 :(得分:5)
基本插入功能:
Function insert(template As String, ParamArray inserts() As Variant) As String
Dim i As Long
For i = 0 To UBound(inserts)
template = Replace$(template, "%" & i + 1 & "%", inserts(i))
Next
'// some special cases perhaps
template = Replace$(template, "%SSPACE%", SSpace(9))
template = Replace$(template, "\r\n", VbCrLf)
insert = template
End Function
对于
?insert("Foo %1% Bar %2% Qux %3% (%1%)", "A", "B", "C")
Foo A Bar B Qux C (A)
地图(添加对 Microsoft Scripting Runtime 的引用):
Dim col As New Scripting.Dictionary
col("name") = "bob"
col("age") = 35
MsgBox insert2("Hello %name% you are %age%", col)
...
Function insert2(template As String, map As Scripting.Dictionary) As String
Dim name
For Each name In map.Keys()
template = Replace$(template, "%" & name & "%", map(name))
Next
insert2 = template
End Function
答案 1 :(得分:2)
Alex K.,谢谢您的解决方案。
以下是我如何扩展它(如果有更好的方法,请随时告诉我)
Function FillTemplateGeneric(template As Variant, map As Scripting.Dictionary) As String
Dim name
Dim out_text As String
' Handle multiple ways of receiving the template string
If VarType(template) = vbString Then
out_text = template
ElseIf VarType(template) = vbArray Then
out_text = Join(template, vbCrLf)
ElseIf TypeName(template) = "String()" Then
out_text = Join(template, vbCrLf)
ElseIf TypeName(template) = "Variant()" And TypeName(template(LBound(template, 1))) = "String" Then
out_text = Join(template, vbCrLf)
Else
MsgBox "Unknown Var Type passed to FillTemplateGeneric as first argument:" & vbCrLf & TypeName(template)
Err.Raise vbObjectError + 513, "FillTemplateGeneric", "Unknown Var Type passed to FillTemplateGeneric as first argument:" & vbCrLf & TypeName(template)
End If
For Each name In map.Keys()
out_text = Replace$(out_text, "%" & name & "%", map(name))
Next
FillTemplateGeneric = out_text
End Function
这允许它接受多种格式的呼叫:
' Common dictionary for expansion
Dim col As New Scripting.Dictionary
col("name") = print_string
' Using inline text for template
MsgBox FillTemplateGeneric("test text with %name% name - just string", col)
' Using a multi-line string
Dim template As String
templ_text = " update_%name% <= 1'b0; // 1 - manual multi-line string" & _
vbCrLf & " %name%_ack_meta <= 1'b0; // " & _
vbCrLf & " %name%_ack_sync <= 1'b0; // "
MsgBox FillTemplateGeneric(templ_text, col)
' Using an array of strings
Dim ttext(1 To 3) As String
ttext(1) = " update_%name% <= 1'b0; // 2 - manual array of strings"
ttext(2) = " %name%_ack_meta <= 1'b0; // "
ttext(3) = " %name%_ack_sync <= 1'b0; // "
MsgBox FillTemplateGeneric(ttext, col)
' Using an inline array of strings
MsgBox FillTemplateGeneric(Array( _
" update_%name% <= 1'b0; // 3 - immediate array of strings", _
" %name%_ack_meta <= 1'b0; // ", _
" %name%_ack_sync <= 1'b0; // " _
), col)