Напишите, если условие в одной строке - PullRequest
0 голосов
/ 12 июня 2019

Есть ли способ записать следующее в одной строке, где функция суммы выполняется только в том случае, если существует поле "InvoiceSum" (и без необходимости повторять поле InvoiceSum)?

If (Doc.MailMerge.GetFieldNames().ToList.Exists(Function(x) x = "InvoiceSum")) Then
  Doc.MailMerge.Execute({"InvoiceSum"}, {GetInvoiceSum()})
End If

Идея состоит в том, чтобы выполнять mailmerge только в том случае, если InvoiceSum существует как поле в документе, потому что функция GetInvoiceSum может быть очень дорогой.

Я бы хотел избежать необходимости оборачивать каждое поле слияния в условие if, которое загрязняет код, но также подвержено ошибкам, поскольку вы должны написать «InvoiceSum» дважды.

Ответы [ 2 ]

1 голос
/ 12 июня 2019

Если у вас есть разные функции для разных полей, вы можете попробовать использовать словарь для указания поля на соответствующую функцию. Затем вы можете отфильтровать словарь по тому, имеет ли он поля 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().

1 голос
/ 12 июня 2019

Если вы выполняете это несколько раз, то, возможно, сохраните результат 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)

Может быть, лучшепередайте Доку также и метод, но я не был уверен в типе, поэтому оставлю это вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...