Function MakeSubstituentFile(XNames() As String, nXNames As Long, XValues() As Variant, nObs As Long, MaxObs As Long, blnAmalgamate As Boolean, MolN As Integer) As Boolean 'coded Sept 2017-20 by James Quinn. This code is placed in the public domain with a standard Open Source license. (Free to use, Use at your own risk.) 'Purpose of routine: Create substructure variables and values given any set of molecules 'This routine uses a great number of globally defined variables as follows: 'nend = number of atoms in the compound (can be multiple molecules) 'nummols = number of molecules in the compound (can be HCl salts for instance.) 'atname() = atomic symbols 'moly() = atomic numbers 'conn() = a 2d array containing the atom connections (dimensioned 6, nend - allowing up to 6 atoms connected to a given atom) 'bond() = a 2d array containing the bond type (1 = single bond, 2 = double bond, 3 = triple bond) 'MolNum() = if multiple molecules, then this array contains which array the atom is in. 'rflag() = if an atom is in a ring, this array contains its ring number 'aromat() = if an atom is in an aromatic ring, this array contains its ring number 'natch() = the number of connections to a given atom 'Variables passed to the routine in the header 'XNames() = the field names created by this routine 'nXNames = the number of substituent fields in the entire dataset 'XValues() = the number of each particular field in each particular compound 'nObs = the number identifying this compound in the dataset, for instance molecule 5 of 100 'MaxObs = the maximum number of field allowed. Used to prevent out of memory errors or array overruns 'blnAmalgamate = true if you wish to amalgamate NO2, #N, OH, CH3, NH2, COOH, halogen. Otherwise it will only amalgamate H, =O, =S 'MolN = the number of the molecule within a mixture to be evaluated. Set to zero if you wish all molecules to be evaluated. Dim i As Long, j As Long, k As Long, m As Long, n As Long, kk As Long, jj As Long, mm As Long, nn As Long, ij As Long, iij As Long, jm As Long, jjm As Long Dim ik As Long, iplace As Integer Dim blnFound As Boolean Dim tmpNend As Long Dim ifound As Integer On Error GoTo ErrMake ReDim tmpAtName(Maxi) As String ReDim tmpconn(6, Maxi) As Long ReDim tmpbond(6, Maxi) As Integer ReDim tmpnatch(Maxi) As Integer ReDim blnSkipMe(Maxi) As Boolean Dim blnSquareMe As Boolean ReDim FoundMe(Maxi) As Integer Dim orig As Integer, path As Integer, pathmax As Integer, oldpath As Long MakeSubstituentFile = False If nend = 0 Then Exit Function tmpNend = nend oldpath = 0 pathmax = 0 iplace = 1 ReDim comboWts(nend) For i = 1 To nend If MolN = 0 Or MolNum(i) = MolN Then tmpAtName(i) = atname$(i) tmpnatch(i) = natch(i) For j = 1 To tmpnatch(i) comboWts(i) = comboWts(i) + moly(conn(j, i)) tmpconn(j, i) = conn(j, i) tmpbond(j, i) = bond(j, i) Next j End If Next i 'Populate the Substituent File with new values... iplace = 2 For i = 1 To tmpNend If MolN = 0 Or MolNum(i) = MolN Then DoEvents If nXNames > 0 Then blnFound = False For j = 1 To nXNames If "Number of " & tmpAtName(i) & " atoms" = XNames(j) Then XValues(j, nObs) = XValues(j, nObs) + 1 blnFound = True End If Next j If blnFound = False Then If nXNames < MaxObs Then nXNames = nXNames + 1 XNames(nXNames) = "Number of " & tmpAtName(i) & " atoms" XValues(nXNames, nObs) = 1 Else Form9.Text1.Text = "Unable to add Number of " & tmpAtName(i) & " atoms because maximum fields (" & MaxObs & ") exceeded." & Chr(10) & Form9.Text1.Text End If End If Else nXNames = 1 XNames(1) = "Number of " & tmpAtName(i) & " atoms" XValues(1, nObs) = 1 End If End If Next 'debug ' For i = 11 To nXNames ' MsgBox XNames(i) ' Next i iplace = 3 If nXNames = 0 Then MakeSubstituentFile = False Exit Function End If 'now for some specific three and four atom pairs that incorporate terminal atoms ReDim nhyds(tmpNend) As Long ReDim nox(tmpNend) As Long ReDim nNTB(tmpNend) As Long For i = 1 To tmpNend If MolN = 0 Or MolNum(i) = MolN Then DoEvents For j = 1 To tmpnatch(i) 'attach hydrogens to parent atom If moly(tmpconn(j, i)) = 1 Then nhyds(i) = nhyds(i) + 1 tmpAtName$(i) = tmpAtName$(i) & "(H)" ElseIf moly(tmpconn(j, i)) = 8 Then nox(i) = nox(i) + 1 End If Next j End If Next i iplace = 4 For i = 1 To tmpNend If MolN = 0 Or MolNum(i) = MolN Then DoEvents If blnAmalgamate = True Then For j = 1 To tmpnatch(i) 'attach fluorine to parent atom If moly(tmpconn(j, i)) = 9 Then tmpAtName$(i) = tmpAtName$(i) & "(F)" End If Next j For j = 1 To tmpnatch(i) 'attach chlorine to parent atom If moly(tmpconn(j, i)) = 17 Then tmpAtName$(i) = tmpAtName$(i) & "(Cl)" End If Next j For j = 1 To tmpnatch(i) 'attach bromine to parent atom If moly(tmpconn(j, i)) = 35 Then tmpAtName$(i) = tmpAtName$(i) & "(Br)" End If Next j For j = 1 To tmpnatch(i) 'attach iodine to parent atom If moly(tmpconn(j, i)) = 53 Then tmpAtName$(i) = tmpAtName$(i) & "(I)" End If Next j End If For j = 1 To tmpnatch(i) If moly(tmpconn(j, i)) = 8 Then If tmpbond(j, i) = 2 Then 'attach double tmpbonded oxygen to parent atom tmpAtName$(i) = tmpAtName$(i) & "(=O)" End If End If Next j If blnAmalgamate = True Then 'attach hydroxy for amalgamations For j = 1 To tmpnatch(i) If moly(tmpconn(j, i)) = 8 Then If tmpbond(j, i) = 1 And nhyds(tmpconn(j, i)) = 1 Then tmpAtName$(i) = tmpAtName$(i) & "(OH)" blnSkipMe(tmpconn(j, i)) = True End If End If Next j End If For j = 1 To tmpnatch(i) 'attach double tmpbonded sulfur to parent atom, except when S has more than one attachment If moly(tmpconn(j, i)) = 16 And tmpbond(j, i) = 2 And tmpnatch(tmpconn(j, i)) = 1 Then tmpAtName$(i) = tmpAtName$(i) & "(=S)" End If Next j For j = 1 To tmpnatch(i) 'attach triple tmpbonded nitrogen to parent except when N has more than one attachement If (moly(tmpconn(j, i)) = 7 And tmpbond(j, i) = 3) And tmpnatch(tmpconn(j, i)) = 1 Then tmpAtName$(i) = tmpAtName$(i) & "(#N)" End If Next j If blnAmalgamate = True Then For j = 1 To tmpnatch(i) 'attach triple tmpbonded nitrogen to parent except when N has more than one attachement If (moly(tmpconn(j, i)) = 7 And tmpbond(j, i) = 1 And tmpnatch(tmpconn(j, i)) = 3) And nhyds(tmpconn(j, i)) = 2 Then 'NH2 tmpAtName$(i) = tmpAtName$(i) & "(NH2)" blnSkipMe(tmpconn(j, i)) = True End If Next j For j = 1 To tmpnatch(i) 'CH3 If moly(tmpconn(j, i)) = 6 And tmpbond(j, i) = 1 And nhyds(tmpconn(j, i)) = 3 Then tmpAtName$(i) = tmpAtName$(i) & "(CH3)" blnSkipMe(tmpconn(j, i)) = True End If Next j End If End If Next i For i = 1 To tmpNend If MolN = 0 Or MolNum(i) = MolN Then If blnAmalgamate = True Then For j = 1 To tmpnatch(i) 'NO2 If moly(tmpconn(j, i)) = 7 And nox(tmpconn(j, i)) > 1 And tmpbond(j, i) = 1 And tmpnatch(tmpconn(j, i)) = 3 Then tmpAtName$(i) = tmpAtName$(i) & "(NO2)" blnSkipMe(tmpconn(j, i)) = True End If Next j End If End If Next i 'debug ' For i = 11 To nXNames ' MsgBox XNames(i) ' Next i iplace = 5 'locate atoms in six membered aromatic rings and put an asterisk after them For i = 1 To tmpNend If MolN = 0 Or MolNum(i) = MolN Then DoEvents If aromat(i) <> 0 Then For j = 1 To tmpnatch(i) jj = tmpconn(j, i) If aromat(jj) <> 0 Then For k = 1 To tmpnatch(j) kk = tmpconn(k, jj) If aromat(kk) <> 0 And kk <> i Then For m = 1 To tmpnatch(kk) mm = tmpconn(m, kk) If aromat(mm) <> 0 And mm <> jj And mm <> i Then For n = 1 To tmpnatch(mm) nn = tmpconn(n, mm) If aromat(nn) <> 0 And nn <> kk And nn <> i Then For ij = 1 To tmpnatch(nn) iij = tmpconn(ij, nn) If aromat(iij) <> 0 And iij <> mm And iij <> i Then For jm = 1 To tmpnatch(iij) jjm = tmpconn(jm, iij) If jjm = i And jjm <> nn And right(tmpAtName(i), 1) <> "*" Then tmpAtName(i) = tmpAtName(i) & "*" Next jm End If Next ij End If Next n End If Next m End If Next k End If Next j End If End If Next i iplace = 6 'other atoms in rings (not aromatic 6) For i = 1 To tmpNend If MolN = 0 Or MolNum(i) = MolN Then If right(tmpAtName$(i), 1) <> "*" Then If rflag(i) > 0 Then tmpAtName$(i) = tmpAtName$(i) & "!" End If End If End If Next i ' urea, carbonate, carbamate are special cases Dim ifound2 As Integer Dim NewNend As Long Dim Skip1 As Boolean Dim Skip2 As Boolean Dim Skip3 As Boolean NewNend = tmpNend iplace = 111 For i = 1 To tmpNend If MolN = 0 Or MolNum(i) = MolN Then blnSquareMe = False ifound = 0 ifound2 = 0 If (moly(i) = 8 And tmpbond(1, i) = 2) Or (moly(i) = 16 And tmpbond(1, i) = 2 And tmpnatch(i) = 1) Then k = tmpconn(1, i) Skip1 = False Skip2 = False Skip3 = False For j = 1 To tmpnatch(k) If tmpbond(j, k) = 1 Then If moly(tmpconn(j, k)) = 7 Then ifound = ifound + 1 If blnSkipMe(tmpconn(j, k)) = True Then If Skip1 = False Then Skip1 = True ElseIf Skip2 = False Then Skip2 = True Else Skip3 = True End If End If ElseIf moly(tmpconn(j, k)) = 8 Then ifound2 = ifound2 + 1 If blnSkipMe(tmpconn(j, k)) = True Then If Skip1 = False Then Skip1 = True ElseIf Skip2 = False Then Skip2 = True Else Skip3 = True End If End If End If End If Next j If ifound > 1 And ifound2 = 0 Then 'NR(=O)N NewNend = NewNend + 1 If ifound = 2 Then If Skip1 = False And Skip2 = False Then tmpAtName(NewNend) = "N" & tmpAtName(k) & "N" GoSub AddName End If ElseIf ifound > 2 Then If Skip1 = False And Skip2 = False And Skip3 = False Then tmpAtName(NewNend) = "N" & tmpAtName(k) & "(N)N" GoSub AddName ElseIf Skip1 = True And Skip2 = False And Skip3 = False Then tmpAtName(NewNend) = tmpAtName(k) & "(N)N" GoSub AddName End If End If ElseIf ifound2 > 1 And ifound = 0 Then 'OR(=O)O NewNend = NewNend + 1 If ifound2 = 2 Then If Skip1 = False And Skip2 = False Then tmpAtName(NewNend) = "O" & tmpAtName(k) & "O" GoSub AddName End If ElseIf ifound2 > 2 Then If Skip1 = False And Skip2 = False And Skip3 = False Then tmpAtName(NewNend) = "O" & tmpAtName(k) & "(O)O" GoSub AddName ElseIf Skip1 = True And Skip2 = False And Skip3 = False Then tmpAtName(NewNend) = tmpAtName(k) & "(O)O" GoSub AddName End If End If ElseIf ifound > 0 And ifound2 > 0 Then 'OR(=O)N NewNend = NewNend + 1 If ifound = 1 And ifound2 = 1 Then If Skip1 = False And Skip2 = False Then tmpAtName(NewNend) = "N" & tmpAtName(k) & "O" GoSub AddName End If ElseIf ifound = 1 And ifound2 > 1 Then If Skip1 = False And Skip2 = False And Skip3 = False Then tmpAtName(NewNend) = "N" & tmpAtName(k) & "(O)O" GoSub AddName ElseIf Skip1 = True And Skip2 = False And Skip3 = False Then tmpAtName(NewNend) = "OR(=O)(O)N of type " & tmpAtName(k) GoSub AddName End If ElseIf ifound > 1 And ifound2 = 1 Then If Skip1 = False And Skip2 = False And Skip3 = False Then tmpAtName(NewNend) = "N" & tmpAtName(k) & "(N)O" GoSub AddName ElseIf Skip1 = True And Skip2 = False And Skip3 = False Then tmpAtName(NewNend) = "OR(=O)(N)N of type " & tmpAtName(k) GoSub AddName End If End If End If End If End If Next i 'PEG and PPG pathmax = 0 For i = 1 To tmpNend If MolN = 0 Or MolNum(i) = MolN Then ifound = 0 For k = 1 To tmpNend FoundMe(k) = 0 Next k If tmpAtName(i) = "O" Then For j = 1 To tmpnatch(i) jj = tmpconn(j, i) If FoundMe(jj) = 0 Then If tmpAtName(jj) = "C(H)(H)" Then ifound = 1 ElseIf tmpAtName(jj) = "C(H)(CH3)" Then ifound = 2 End If If ifound > 0 Then For m = 1 To tmpnatch(jj) mm = tmpconn(m, jj) If mm <> i And FoundMe(mm) = 0 Then If ifound = 1 And tmpAtName(mm) = "C(H)(H)" Then ifound = 3 ElseIf ifound = 1 And tmpAtName(mm) = "C(H)(CH3)" Then ifound = 4 ElseIf ifound = 2 And tmpAtName(mm) = "C(H)(H)" Then ifound = 4 End If End If If ifound > 2 Then For n = 1 To tmpnatch(mm) nn = tmpconn(n, mm) If nn <> jj And nn <> i Then If tmpAtName(nn) = "O" Then If ifound = 3 Then NewNend = NewNend + 1 tmpAtName(NewNend) = "OCH2CH2O" blnSquareMe = True FoundMe(jj) = 1 FoundMe(mm) = 1 GoSub AddName ElseIf ifound = 4 Then NewNend = NewNend + 1 tmpAtName(NewNend) = "OCH(CH3)CH2O" blnSquareMe = True GoSub AddName FoundMe(jj) = 1 FoundMe(mm) = 1 End If End If End If Next n End If Next m End If End If Next j End If End If Next i blnFound = False For i = 1 To tmpNend 'find longest carbon only path If MolN = 0 Or MolNum(i) = MolN Then If moly(i) = 6 Then path = 1 For k = 1 To tmpNend FoundMe(k) = 0 Next k FoundMe(i) = 1 For j = 1 To tmpnatch(i) jj = tmpconn(j, i) If moly(jj) = 6 And FoundMe(jj) = False Then path = 2 FoundMe(jj) = 1 Call findCPath(jj, i, path, 6, FoundMe(), moly(), tmpnatch(), conn(), pathmax, MolNum(), 0) End If If pathmax < path Then pathmax = path If pathmax > oldpath Or blnFound = False Then If blnFound = False Then NewNend = NewNend + 1 blnFound = True oldpath = pathmax tmpAtName(NewNend) = "Number of consecutive carbons" GoSub AddName End If Next j End If End If Next i ' tmpNend = NewNend ifound = 0 iplace = 7 'debug ' For i = 11 To nXNames ' MsgBox XNames(i) ' Next i 'two atom pairs ( + hydrogens, #N, =O and =S attached to them) Dim strChar As String For ik = 1 To nummols ifound = 0 iplace = 8 For i = 1 To tmpNend - 1 'no need to consider last number as then k < i... If MolN = 0 Or MolNum(i) = MolN Then DoEvents If MolNum(i) = ik Then If moly(i) = 1 Then GoTo skipme 'H If moly(i) = 9 And blnAmalgamate = True Then GoTo skipme 'F If moly(i) = 17 And blnAmalgamate = True Then GoTo skipme 'Cl If moly(i) = 35 And blnAmalgamate = True Then GoTo skipme 'Br If moly(i) = 53 And blnAmalgamate = True Then GoTo skipme 'I If moly(i) = 8 And tmpbond(1, i) = 2 Then GoTo skipme '=O If moly(i) = 8 And blnAmalgamate = True And nhyds(i) = 1 Then GoTo skipme 'OH If moly(i) = 16 And (tmpbond(1, i) = 2 And tmpnatch(i) = 1) Then GoTo skipme '=S If moly(i) = 7 And tmpbond(1, i) = 3 And tmpnatch(i) = 1 Then GoTo skipme 'C#N, N#N etc. If moly(i) = 7 And blnAmalgamate = True And nhyds(i) = 2 And tmpnatch(i) = 3 Then GoTo skipme 'NH2 If moly(i) = 7 And blnAmalgamate = True And nox(i) > 1 And tmpnatch(i) = 3 Then GoTo skipme 'NO2 If moly(i) = 6 And blnAmalgamate = True And nhyds(i) = 3 And tmpnatch(i) = 4 Then GoTo skipme 'CH3 For kk = 1 To tmpnatch(i) k = tmpconn(kk, i) If moly(k) = 1 Then GoTo Skiptmpnatch If moly(k) = 9 And blnAmalgamate = True Then GoTo Skiptmpnatch If moly(k) = 8 Then If tmpbond(kk, i) = 2 Then '=O GoTo Skiptmpnatch ElseIf blnAmalgamate = True Then 'OH If nhyds(k) = 1 Then GoTo Skiptmpnatch End If End If If moly(k) = 16 And tmpbond(kk, i) = 2 And tmpnatch(k) = 1 Then GoTo Skiptmpnatch If moly(k) = 17 And blnAmalgamate = True Then GoTo Skiptmpnatch If moly(k) = 35 And blnAmalgamate = True Then GoTo Skiptmpnatch If moly(k) = 53 And blnAmalgamate = True Then GoTo Skiptmpnatch If moly(k) = 7 And tmpbond(kk, i) = 3 And tmpnatch(k) = 1 Then GoTo Skiptmpnatch '#N If moly(k) = 7 And blnAmalgamate = True And nhyds(k) = 2 And tmpnatch(k) = 3 Then GoTo Skiptmpnatch 'NH2 If moly(k) = 7 And blnAmalgamate = True And nox(k) > 1 And tmpnatch(k) = 3 Then GoTo Skiptmpnatch 'NO2 If moly(k) = 6 And blnAmalgamate = True And tmpbond(kk, i) = 1 And nhyds(k) = 3 Then GoTo Skiptmpnatch 'CH3 If right(tmpAtName(k), 1) = "*" And right(tmpAtName(i), 1) = "*" Then ' aromatic 6 same ring strChar = "" Else Select Case tmpbond(kk, i) Case 1 strChar = "-" Case 2 strChar = "=" Case 3 strChar = "#" End Select End If blnFound = False If k > i Then 'only consider each pair once For j = 1 To nXNames If "Number of " & tmpAtName(i) & strChar & tmpAtName(k) & " pairs" = XNames(j) Or "Number of " & tmpAtName(k) & strChar & tmpAtName(i) & " pairs" = XNames(j) Then XValues(j, nObs) = XValues(j, nObs) + 1 blnFound = True ifound = ifound + 1 End If Next j If blnFound = False Then 'new pairs If nXNames = MaxObs Then Form9.Text1.Text = "Maximum number of variables reached (" & MaxObs & ")..." & Chr(13) & Chr(10) & Form9.Text1.Text GoTo Skiptmpnatch End If nXNames = nXNames + 1 If moly(i) < moly(k) Then XNames(nXNames) = "Number of " & tmpAtName(i) & strChar & tmpAtName(k) & " pairs" ElseIf moly(i) = moly(k) Then If Len(tmpAtName(i)) < Len(tmpAtName(k)) Then XNames(nXNames) = "Number of " & tmpAtName(i) & strChar & tmpAtName(k) & " pairs" ElseIf Len(tmpAtName(i)) = Len(tmpAtName(k)) Then If right(tmpAtName(k), 1) = "*" And right(tmpAtName(i), 1) <> "*" Then XNames(nXNames) = "Number of " & tmpAtName(k) & strChar & tmpAtName(i) & " pairs" ElseIf right(tmpAtName(k), 1) <> "*" And right(tmpAtName(i), 1) = "*" Then XNames(nXNames) = "Number of " & tmpAtName(i) & strChar & tmpAtName(k) & " pairs" Else If nhyds(k) > nhyds(i) Then XNames(nXNames) = "Number of " & tmpAtName(i) & strChar & tmpAtName(k) & " pairs" ElseIf nhyds(i) > nhyds(k) Then XNames(nXNames) = "Number of " & tmpAtName(k) & strChar & tmpAtName(i) & " pairs" Else If comboWts(i) > comboWts(k) Then XNames(nXNames) = "Number of " & tmpAtName(k) & strChar & tmpAtName(i) & " pairs" Else XNames(nXNames) = "Number of " & tmpAtName(i) & strChar & tmpAtName(k) & " pairs" End If End If End If Else XNames(nXNames) = "Number of " & tmpAtName(k) & strChar & tmpAtName(i) & " pairs" End If Else XNames(nXNames) = "Number of " & tmpAtName(k) & strChar & tmpAtName(i) & " pairs" End If XValues(nXNames, nObs) = 1 ifound = ifound + 1 End If End If Skiptmpnatch: Next kk End If skipme: End If Next i 'debug ' For i = 11 To nXNames ' MsgBox XNames(i) ' Next i iplace = 9 Dim iLength As Integer Dim atFound As Long If ifound = 0 Then For i = 1 To tmpNend If MolN = 0 Or MolNum(i) = MolN Then If MolNum(i) = ik Then iLength = Len(tmpAtName$(i)) atFound = i j = i Exit For End If End If Next i iplace = 10 For i = j + 1 To tmpNend If MolN = 0 Or MolNum(i) = MolN Then If MolNum(i) = ik Then If Len(tmpAtName$(i)) > iLength Then atFound = i iLength = Len(tmpAtName$(i)) ElseIf Len(tmpAtName$(i)) = iLength Then If moly(i) < moly(atFound) Then atFound = i End If End If End If Next i iplace = 11 blnFound = False For j = 1 To nXNames If nummols > 1 Then If XNames(j) = "Number of H(Cl)" Then XNames(j) = XNames(j) & "_salt" If XNames(j) = "Number of H(F)" Then XNames(j) = XNames(j) & "_salt" If XNames(j) = "Number of H(Br)" Then XNames(j) = XNames(j) & "_salt" If XNames(j) = "Number of H(I)" Then XNames(j) = XNames(j) & "_salt" If XNames(j) = "Number of O(H)(H)" Then XNames(j) = XNames(j) & "_hydride" End If If "Number of " & tmpAtName(atFound) = XNames(j) Or "Number of " & tmpAtName(atFound) & "_salt" = XNames(j) Or "Number of " & tmpAtName(atFound) & "_hydride" = XNames(j) Then XValues(j, nObs) = XValues(j, nObs) + 1 blnFound = True ifound = ifound + 1 End If Next j iplace = 12 If blnFound = False Then 'new If nXNames = MaxObs Then Exit Function nXNames = nXNames + 1 XNames(nXNames) = "Number of " & tmpAtName(atFound) XValues(nXNames, nObs) = 1 If nummols > 1 Then If XNames(j) = "Number of H(Cl)" Then XNames(j) = XNames(j) & "_salt" If XNames(j) = "Number of H(F)" Then XNames(j) = XNames(j) & "_salt" If XNames(j) = "Number of H(Br)" Then XNames(j) = XNames(j) & "_salt" If XNames(j) = "Number of H(I)" Then XNames(j) = XNames(j) & "_salt" If XNames(j) = "Number of O(H)(H)" Then XNames(j) = XNames(j) & "_hydride" End If End If End If Next ik 'debug ' For i = 11 To nXNames ' MsgBox XNames(i) ' Next i iplace = 13 MakeSubstituentFile = True Exit Function AddName: iplace = 112 For j = 1 To nXNames If "Number of " & tmpAtName(NewNend) & " Groups" = XNames(j) Then XValues(j, nObs) = XValues(j, nObs) + 1 If blnSquareMe = True Then XValues(j + 1, nObs) = XValues(j, nObs) * XValues(j, nObs) XValues(j + 2, nObs) = Sqr(XValues(j, nObs)) End If Return ElseIf "Number of consecutive carbons" = XNames(j) Then XValues(j, nObs) = pathmax XValues(j + 1, nObs) = XValues(j, nObs) * XValues(j, nObs) XValues(j + 2, nObs) = Sqr(XValues(j, nObs)) Return End If Next j iplace = 113 If nXNames = MaxObs Then Exit Function nXNames = nXNames + 1 If left(tmpAtName(NewNend), 21) <> "Number of consecutive" Then XNames(nXNames) = "Number of " & tmpAtName(NewNend) & " Groups" XValues(nXNames, nObs) = 1 If blnSquareMe = True Then nXNames = nXNames + 1 XNames(nXNames) = "Number of " & tmpAtName(NewNend) & " Groups Squared" XValues(nXNames, nObs) = 1 nXNames = nXNames + 1 XNames(nXNames) = "Square_root_of_" & tmpAtName(NewNend) XValues(nXNames, nObs) = 1 End If Else XNames(nXNames) = tmpAtName(NewNend) XValues(nXNames, nObs) = pathmax nXNames = nXNames + 1 XNames(nXNames) = tmpAtName(NewNend) & " Squared" XValues(nXNames, nObs) = pathmax * pathmax nXNames = nXNames + 1 XNames(nXNames) = "Square_root_of_" & tmpAtName(NewNend) XValues(nXNames, nObs) = Sqr(pathmax) End If Return ErrMake: Form9.Text1.Text = Err.Description & " in the MakeSubstituentFile Routine. Place = " & iplace & Chr(13) & Chr(10) & Form9.Text1.Text If nXNames > MaxObs Then nXNames = MaxObs MakeSubstituentFile = False End Function Sub findCPath(i As Long, oldi As Long, path%, pathtype As Integer, foundit%(), moly() As Integer, natch() As Integer, conn() As Integer, pathmax As Integer, MolNum() As Integer, MolN As Integer) ' routine for finding the longest path of consecutive carbons ' calls itself recursively ' moly(n) atomic number of atom n ' natch(n) the number of atoms bonded to atom n ' conn(i,n) the identity of the atom of the connection i to atom n. ' MolN = the molecule number to consider. If all molecules then MolN=0. ' MolNum(n) = the molecule number containing atom n ' pathtype = a second atom type to include in the chain. if Pathtype =7 it will find the longest chain of carbon and nitrogen, if 8 then the path with oxygen and carbon etc. Dim PathOK As Boolean Dim n As Long Dim oldn As Long On Error GoTo GetOut PathOK = False oldpath% = path% For j% = 1 To natch(i) n = conn(j%, i) If MolNum(n) = MolN Or MolN = 0 And n <> oldi Then If moly(n) = 6 Then PathOK = True If moly(n) = pathtype Then PathOK = True If moly(n) = 8 And pathtype = 15 Then PathOK = True If PathOK = True Then If foundit%(n) = 0 Then 'found another one path% = path% + 1 If path% > pathmax Then pathmax = path% foundit%(n) = 1 oldn = i 'don't go back Call findCPath(n, oldn, path%, pathtype, foundit%(), moly(), natch(), conn(), pathmax, MolNum(), MolN) path% = oldpath% End If End If End If ' MsgBox molname$(1) PathOK = False Next j% Leave: Exit Sub GetOut: Err = 0 Resume Leave End Sub