Vba Visual Basic for Applications中的文本模板引擎/函数

Vba Visual Basic for Applications中的文本模板引擎/函数,vba,excel,Vba,Excel,VBA在我公司的一个常见用法是根据Excel表格中输入的信息生成源代码。鉴于VBA的本机字符串操作,执行此操作的代码编写起来很繁琐,可读性也不高 一个简单的例子(这些变得更复杂)是: Print#fileIdentifier、SSpace(9)和“update”&Print#u string和“[”&CStr(j)和“]基本插入功能: Function insert(template As String, ParamArray inserts() As Variant) As String

VBA在我公司的一个常见用法是根据Excel表格中输入的信息生成源代码。鉴于VBA的本机字符串操作,执行此操作的代码编写起来很繁琐,可读性也不高

一个简单的例子(这些变得更复杂)是:


Print#fileIdentifier、SSpace(9)和“update”&Print#u string和“[”&CStr(j)和“]基本插入功能:

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
为了

映射(添加对Microsoft脚本运行时的引用):


Alex K.,谢谢你的解决方案

下面是我如何扩展它的(如果有更好的方法,请随时告诉我)

这允许它接受多种格式的呼叫:

' 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)
用于扩展的通用字典 Dim col作为新的脚本。字典 col(“name”)=打印字符串 '为模板使用内联文本 MsgBox FillTemplateGeneric(“带有%name%name的测试文本-仅字符串”,col) '使用多行字符串 将模板设置为字符串
temp_text=“update_u%name%将模板文本存储在文件中,加载它并进行replace$()调用?生成代码的语言是什么?谢谢@AlexK。谢谢你的建议。有数百段这样的代码需要填写,因此文本必须内联存储。我认为手动调用来替换@label@字符串的所有实例是可行的,但它仍然比我要寻找的代码多得多,特别是当模板文本变长并且包含更多要替换的“变量”时。您总是需要更改print语句以适应任何新的内容,可以将您的示例重新分解为一个过程,该过程使用带有顺序插入标记的模板字符串:
update_@1@[@2@]\r\nXXX@3@
然后一组值变量将“模板”存储在文本文件中。在VBA中打开它,并根据Excel工作表中存储的数据执行替换。将其写入一个新的唯一文件。谢谢。这很有效。在这变得足够干净以满足我最终的需求之前,还有一些调整,但这肯定解决了我的问题。很好。您可以通过在一个类中填充逻辑并使用一系列
template.add“line 1”来整理多行concats/&u。。。template.add“line x”
调用。
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)
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
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)