有没有一种方法可以在一行中编写以下内容,而sum函数仅在“ InvoiceSum”字段存在时才执行(而不必重复InvoiceSum字段)?
If (Doc.MailMerge.GetFieldNames().ToList.Exists(Function(x) x = "InvoiceSum")) Then
Doc.MailMerge.Execute({"InvoiceSum"}, {GetInvoiceSum()})
End If
想法是仅在InvoiceSum作为文档中的字段存在的情况下执行邮件合并,因为GetInvoiceSum函数可能非常昂贵。
我想避免必须将每个合并字段都包装在if条件中,这会污染代码,但也容易出错,因为您必须两次编写“ InvoiceSum”。
答案 0 :(得分:1)
如果您多次执行此操作,则可以存储Doc.MailMerge.GetFieldNames()的结果,而不是每次都调用它。
根据我发现的文档,Doc.MailMerge.GetFieldNames()返回一个字符串数组。如果是这样,请尝试以下操作:
Dim FieldNames As String() = Doc.MailMerge.GetFieldNames()
If FieldNames.Contains("InvoiceSum") Then Doc.MailMerge.Execute({"InvoiceSum"}, {GetInvoiceSum()})
或者如果您想创建一个方法,请尝试以下操作:
Private Sub MergeIfExists(FieldName As String, FieldNames As String(), Action As Action)
If FieldNames.Contains(FieldName) Then Doc.MailMerge.Execute({FieldName}, {Action})
End Sub
用法:
Dim FieldNames As String() = Doc.MailMerge.GetFieldNames()
MergeIfExists("InvoiceSum", FieldNames, AddressOf GetInvoiceSum)
也许也可以将Doc传递给该方法,但是我不确定类型,所以将其留给您。
答案 1 :(得分:1)
如果不同字段的功能不同,则可能需要尝试使用字典将字段指向相应的功能。然后,您可以根据字典是否具有MailMerge字段作为键来过滤字典。然后,仅对过滤的字段执行该功能。
' build your dictionary of [fieldname, function] somehow
Dim fieldsAndFunctions As New Dictionary(Of String, Func(Of Object))()
fieldsAndFunctions.Add("InvoiceSum", AddressOf GetInvoiceSum)
fieldsAndFunctions.Add("InvoiceAvg", AddressOf GetInvoiceAvg)
fieldsAndFunctions.Add("InvoiceMax", AddressOf GetInvoiceMax)
' get the field names once
Dim existingFields = doc.MailMerge.GetFieldNames()
' filter your dictionary down to only the items whose field names are in your MailMerge object
Dim filteredFieldsAndFunctions = fieldsAndFunctions.
Where(Function(kvp) existingFields.Contains(kvp.Key))
' call execute, passing the fields and values as arrays
If filteredFieldsAndFunctions.Any() Then
doc.MailMerge.Execute(
filteredFieldsAndFunctions.Select(Function(f) f.Key).ToArray(),
filteredFieldsAndFunctions.Select(Function(f) f.Value()).ToArray())
End If
仅对存在的字段最后计算值。请注意()
的缩写Func.Invoke()
。