5
\$\begingroup\$

This was a revision, made when the code failed after an update (at least that is what I think happened).

So I fixed it and now it works, but I think that this code can be written better and more efficiently, and perhaps made easier to read. Note that VBScript/VBA/VB6 isn't (aren't) my primary language(s), the closest thing I do is C#.

I presume that the If statements can be whittled down a little bit, (I know they can).

I am unsure of the version/flavor of VB this is, but given that it is written inside <script> tags I presume it's VBScript.

Public Function GetParameterXml()
  GetParameterXml = _
  "<Parameters>" &_
  "  <Parameter Value='TYPE' Code='T' Description='Type' Type='Combo' Tooltip='Select parameters from the drop down list.'>" &_
  "    <Options>" &_
  "  <Option Code='1' Description='Assignee Name' Value='A' />" &_
  "  <Option Code='2' Description='Creditor Name' Value='C' />" &_
  "  <Option Code='3' Description='Debtor Name' Value='D' />" &_
  "    </Options>" &_
  "  </Parameter>" &_
  "  <Parameter Value='NAMEFORMAT' Code='T' Description='Name Format' Type='Combo' Tooltip='Select parameters from the drop down list.'>" &_
  "    <Options>" &_
  "  <Option Code='11' Description='First Mid Last' Value='1' />" &_
  "  <Option Code='12' Description='Last, First Mid' Value='2' />" &_
  "  <Option Code='13' Description='Last, First' Value='3' />" &_
  "  <Option Code='14' Description='Last, First, Mid' Value='4' />" &_
  "    </Options>" &_
  "  </Parameter>" &_
  "</Parameters>"
End Function

Dim Parameter: Set Parameter = Parameters.Item(Bookmark,"TYPE")
Dim Parameter2: Set Parameter2 = Parameters.Item(Bookmark,"NAMEFORMAT")
Dim sTemp
Dim oNodes: Set oNodes = Nothing
Dim oNode: Set oNode = Nothing
Dim PartyName()
Dim ArrayIndex
Dim varPartyName
Dim FirstName
Dim MidName
Dim LastName
Dim ParameterValue
Dim Suffix
ReturnData = ""

If Parameter2 is Nothing Then
  ParameterValue = "1"
Else 
  ParameterValue = Parameter2.value
End If

ArrayIndex = 0

If Not Parameter is Nothing Then
  Set oNodes = xmlDoc.selectNodes("/Record/CelloXml/Integration/Case/JudgmentEvent/Judgment/Additional/SDMonetaryAward/SDMonetaryAwardParties/SDMonetaryAwardParty[PartyConnection[@Word='"& uCase(parameter.Value) &"']]")

  For each oNode in oNodes
    For each oNode2 in oNode.childNodes
        If oNode2.nodeName = "PartyName" Then
            ReDim Preserve PartyName(ArrayIndex)
            PartyName(ArrayIndex) = oNode2.text
            ArrayIndex = ArrayIndex + 1
        End If
    Next
  Next

  For each varPartyName in PartyName

    dim FirstMiddleName
    LastName = Split(varPartyName, ",")(0)
    FirstMiddleName = Trim(Split(varPartyName,",")(1))
    Suffix = Trim(Split(VarPartyName,",")(2))
    MidName = Trim(Split(FirstMiddleName, " ")(1))
    FirstName = Trim(Split(FirstMiddleName, " ")(0))

    If ParameterValue = "1" Then
      If IsNull(FirstName) and IsNull(MidName) Then
        ReturnData = ReturnData & LastName & Chr(13) & Chr(10)
      ElseIf IsNull(MidName) Then
        If IsNull(Suffix) Then
            ReturnData = ReturnData & FirstName & " " & LastName & Chr(13) & Chr(10)
        Else
            ReturnData = ReturnData & FirstName & " " & LastName & " " & Suffix & Chr(13) & Chr(10)
        End If
      Else
        If IsNull(Suffix) Then
            ReturnData = ReturnData & FirstName & " " & MidName & " " & LastName & Chr(13) & Chr(10)
        Else
            ReturnData = ReturnData & FirstName & " " & MidName & " " & LastName & " " & Suffix & Chr(13) & Chr(10)
        End If
      End If
    ElseIf ParameterValue = "2" Then
      If IsNull(FirstName) and IsNull(MidName) Then
        ReturnData = ReturnData & LastName & Chr(13) & Chr(10)
      ElseIf IsNull(MidName) Then
        If IsNull(Suffix) Then
            ReturnData = ReturnData & LastName & ", " & FirstName & Chr(13) & Chr(10)
        Else
            ReturnData = ReturnData & LastName & ", " & FirstName & " " & Suffix & Chr(13) & Chr(10)
        End If
      Else
        If IsNull(Suffix) Then
            ReturnData = ReturnData & LastName & ", " & FirstName & " " & MidName & Chr(13) & Chr(10)
        Else
            ReturnData = ReturnData & LastName & ", " & FirstName & " " & MidName & " " & Suffix & Chr(13) & Chr(10)
        End If
      End If
    ElseIf ParameterValue = "3" Then
      If IsNull(FirstName) Then
        ReturnData = ReturnData & LastName & Chr(13) & Chr(10)
      Else
        If IsNull(Suffix) Then
            ReturnData = ReturnData & LastName & ", " & FirstName & Chr(13) & Chr(10)
        Else
            ReturnData = ReturnData & LastName & ", " & FirstName & " " & Suffix & Chr(13) & Chr(10)
        End If
      End If
    ElseIf ParameterValue = "4" Then
      If IsNull(FirstName) and IsNull(MidName) Then
        ReturnData = ReturnData & LastName & Chr(13) & Chr(10)
      ElseIf IsNull(MidName) Then
        If IsNull(Suffix) Then
            ReturnData = ReturnData & LastName & ", " & FirstName & Chr(13) & Chr(10)
        Else
            ReturnData = ReturnData & LastName & ", " & FirstName & Suffix & Chr(13) & Chr(10)
        End If
      Else
        If IsNull(Suffix) Then
            ReturnData = ReturnData & LastName & ", " & FirstName & ", " & MidName & Chr(13) & Chr(10)
        Else 
            ReturnData = ReturnData & LastName & ", " & FirstName & " " & Suffix & ", " & MidName & Chr(13) & Chr(10)
        End If
      End If
    End If
    FirstName = Null
    LastName = Null
    MidName = Null
    FirstMiddleName = Null
    Suffix = Null
  Next

End If

Erase PartyName

If Len(ReturnData) > 0 Then
  ReturnData = Left(ReturnData, Len(ReturnData)-2)
End If

Again, this is code that I fixed and added to.

Input from the XML for the name comes in this format:

Johnson, James T, {optional-Suffix}

\$\endgroup\$
  • 1
    \$\begingroup\$ Yay, a cyclomatic complexity party!! I'll look at this when I have a chance :) \$\endgroup\$ – Mathieu Guindon Oct 30 '13 at 20:31
  • \$\begingroup\$ I'll just say that every single Chr(13) & Chr(10) in there could very well be replaced with vbNullString :) \$\endgroup\$ – Mathieu Guindon Oct 30 '13 at 20:34
  • \$\begingroup\$ I think it is supposed to be a newline character. this code runs a token that populates on a word document inside of a third party application, lots of fun! would the vbNullString behave like a newline? I guess that might be determined by the rules of the main application too? \$\endgroup\$ – Malachi Oct 30 '13 at 21:30
  • 1
    \$\begingroup\$ Oh darn, what an epic typo/brainfart! I meant vbNewLine!! Sorry! \$\endgroup\$ – Mathieu Guindon Oct 30 '13 at 22:41
  • 1
    \$\begingroup\$ vbNullString is equivalent to "".. \$\endgroup\$ – Mathieu Guindon Oct 30 '13 at 22:46
6
\$\begingroup\$

I'm assuming this is VBScript, and I'm not familiar at all with VBScript, and it seems pretty different from VBA/VB6 as far as iterating arrays (can't do For Each on an array in VBA/VB6) and string nullability is concerned - and VBA/VB6 isn't exactly crystal-clear as to what means what.

From this source (dates back from 2000, quotes a dead Microsoft link - emphasis & formatting mine):

  • "": A zero-length string (commonly called an "empty string") is technically a zero-length BSTR that actually uses six bytes of memory. In general, you should use the constant vbNullString instead, particularly when calling external DLL procedures.

  • Empty: A variant of VarType 0 (vbEmpty) that has not yet been initialized. Test whether it is "nil" using the IsEmpty function.

  • Nothing: Destroys an object reference using the Set statement. Test whether it is "nil" using the Is operator.

  • Null: A variant of VarType 1 (vbNull) that means "no valid data" and generally indicates a database field with no value. Don't confuse this with a C NULL, which indicates zero. Test whether it is "nil" using the IsNull function.

  • vbNullChar: A character having a value of zero. It is commonly used for adding a C NULL to a string or for filling a fixed-length string with zeroes.

  • vbNullString: A string having a value of zero, such as a C NULL, that takes no memory. Use this string for calling external procedures looking for a null pointer to a string. To distinguish between vbNullString and "", use the VBA StrPtr function: StrPtr(vbNullString) is zero, while StrPtr("") is a nonzero memory address.


So, it being a script, I'm not going to try to go and define classes here, although it seems to be supported. I'm still trying to wrap my head around all those conditions!

The conditions (and the fact that they are repeated in all main 4 branches) are actually hiding the intent.

So I would write a little Coalesce function and do away with all those checks:

 Public Function Coalesce(ByVal value)
     If IsNull(value) Then
         Coalesce = vbNullString
     Else
         Coalesce = CStr(value)
     End If
 End Function

You seem to have a fixed amount of possible values for ParameterValue, to me this looks like a job for some Select Case rather than an If...ElseIf...ElseIf... block - also, separate the concerns of figuring out a line's content and of appending it to the result - because it's the ParameterValue that determines the order of the names, whether they're present or not doesn't matter, they can all be appended - as long as we ensure to replace Null values with non-value vbNullString:

'note: LastName can't ever be null... unless nothing was supplied at all.
Dim lineResult
Select Case ParameterValue

    Case "1": 
        'First Mid Last [Suffix]
        lineResult = Trim(Coalesce(FirstName) & " " _
                        & Coalesce(MidName) & " " _
                        & Coalesce(LastName) & " " _
                        & Coalesce(Suffix))

    Case "2": 
        'Last, First Mid [Suffix]
        lineResult = Trim(Coalesce(LastName) & ", " _
                        & Coalesce(FirstName) & " " _
                        & Coalesce(MidName) & " " _
                        & Coalesce(Suffix))

    Case "3": 
        'Last, First [Suffix] ~> Middle name ignored?
        lineResult = Trim(Coalesce(LastName) & ", " _
                        & Coalesce(FirstName) & " " _
                        & Coalesce(Suffix))

    Case "4": 
        'Last, First [Suffix], Mid
        lineResult = Trim(Coalesce(LastName) & ", " _
                        & Coalesce(FirstName) & " " _
                        & Coalesce(Suffix) & ", " _
                        & Coalesce(MidName))

End Select

This leaves us, in the worst cases, with a lineResult that's ended with ", ," or ",". Easy fix - not so neat, but hey between that and a bunch of nested If statements, I go with this:

If Right(lineResult, 2) = " ," Then lineResult = Left(lineResult, Len(lineResult) - 2)
If Right(lineResult, 1) = "," Then lineResult = Left(lineResult, Len(lineResult) - 1)

Now all we're missing is lineResult = lineResult & vbNewLine, and then we can do ReturnData = ReturnData & lineResult, and then we can iterate again.

\$\endgroup\$
  • \$\begingroup\$ Gotta say I haven't tested any of this, but I'm quite confident you'd get the exact same results as you do now. \$\endgroup\$ – Mathieu Guindon Nov 1 '13 at 1:04
  • 1
    \$\begingroup\$ well they want me to take out some of the options for this token, so I will have a chance to change the code again, hopefully the version that this application is using will support the things that you have here, I will check into it and let you know \$\endgroup\$ – Malachi Nov 1 '13 at 13:21
  • \$\begingroup\$ otherwise it looks very nice. \$\endgroup\$ – Malachi Nov 1 '13 at 13:21
  • 1
    \$\begingroup\$ Thanks! I think Case "3" could be dropped, it ends up with the same format as Case "4" (given #4 would have Mid optional) so if you don't have a MidName they both output the same result. \$\endgroup\$ – Mathieu Guindon Nov 1 '13 at 13:32
  • 2
    \$\begingroup\$ Very Elegant, no Bugs yet. now I know when I ask Questions about this it's VBSCRIPT! \$\endgroup\$ – Malachi Nov 4 '13 at 20:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.