How to split a string every fourth delimiter? - vba

Is it possible to split a string every fourth delimiter?
We receive a text file that has one string containing several days data.
I would like to split once using the '|' as the delimiter, but different days data is joined by a comma.
Option Explicit
Sub Split4thdelim()
Dim strOriginal as string
Dim originalArry() as string
Dim X as long
strOriginal = "01/01/2020|user1,89|user2,90|user3,99,02/01/2020|user1,80|user2,85|user3,97,03/01/2020|user1,88|user2,96|user3,99"
originalArry = split(strOriginal,"|")
For X = originalArry(originalArry(Lbound)) to originalArry(originalArry(Ubound))
Debug.Print originalArry(X)
Next
End Sub
I would like to split it like this:
01/01/2020
user1,89
user2,90
user3,99
02/01/2020
user1,80
user2,85
user3,97
03/01/2020
user1,88
user2,96
user3,99

Sub Split4thdelim()
Dim strOriginal As String
Dim originalArry() As String
Dim X As Long, n As Long
strOriginal = "01/01/2020|user1,89|user2,90|user3,99,02/01/2020|user1," & _
"80|user2,85|user3,97,03/01/2020|user1,88|user2,96|user3,99"
'replace every fourth "," with chr(0)
For X = 1 To Len(strOriginal)
If Mid(strOriginal, X, 1) = "," Then
n = n + 1
If n Mod 4 = 0 Then Mid(strOriginal, X, 1) = Chr(0)
End If
Next X
originalArry = Split(strOriginal, Chr(0))
For X = LBound(originalArry) To UBound(originalArry)
Debug.Print Join(Split(originalArry(X), "|"), vbLf)
Next
End Sub

Do it manually:
Sub Split4thdelim()
Dim strOriginal As String
Dim Token As New Collection
Dim strToken As String
Dim X As Long
strOriginal = "01/01/2020|user1,89|user2,90|user3,99,02/01/2020|user1,80|user2,85|user3,97,03/01/2020|user1,88|user2,96|user3,99"
Dim Pos As Long
Dim strTemp As String
Pos = InStr(1, strOriginal, "user")
Token.Add Mid(strOriginal, 1, Pos - 2)
strOriginal = Right(strOriginal, Len(strOriginal) - Pos + 1)
While Pos > 0
Pos = InStr(2, strOriginal, "user")
Token.Add Mid(strOriginal, 1, Pos - 2)
strOriginal = Right(strOriginal, Len(strOriginal) - Pos + 1)
Pos = InStr(2, strOriginal, "user")
Token.Add Mid(strOriginal, 1, Pos - 2)
strOriginal = Right(strOriginal, Len(strOriginal) - Pos + 1)
Pos = InStr(2, strOriginal, "user")
If Pos = 0 Then 'no more user, so this is the last set
Token.Add Right(strOriginal, Len(strOriginal) - Pos)
Else
strTemp = Left(strOriginal, Pos - 2)
strOriginal = Right(strOriginal, Len(strOriginal) - Pos + 1) 'save new strOriginal
Pos = InStr(1, strOriginal, ",")
strToken = Mid(strTemp, 1, Pos)
strTemp = Right(strTemp, Len(strTemp) - Pos)
Pos = InStr(1, strTemp, ",")
If Pos = 0 Then
Pos = InStr(1, strTemp, "|")
End If
strToken = strToken + Mid(strTemp, 1, Pos - 1)
Token.Add strToken
Token.Add Right(strTemp, Len(strTemp) - Pos)
End If
Wend
Dim strItem As Variant
For Each strItem In Token
Debug.Print strItem
Next strItem
End Sub

Try,
Sub Split4thdelim()
Dim strOriginal As String
Dim originalArry() As String
Dim X As Long
Dim vSplit, s As String, s2 As String
Dim vR()
Dim n As Long
strOriginal = "01/01/2020|user1,89|user2,90|user3,99,02/01/2020|user1,80|user2,85|user3,97,03/01/2020|user1,88|user2,96|user3,99"
originalArry = Split(strOriginal, "|")
For X = LBound(originalArry) To UBound(originalArry)
'Debug.Print originalArry(X)
s = originalArry(X)
If InStr(s, "/") And InStr(s, ",") Then
n = n + 2
vSplit = Split(s, ",")
s2 = vSplit(UBound(vSplit))
ReDim Preserve vR(1 To n)
vR(n - 1) = Replace(s, "," & s2, "")
vR(n) = s2
Else
n = n + 1
ReDim Preserve vR(1 To n)
vR(n) = s
End If
Next
Range("a1").Resize(n) = WorksheetFunction.Transpose(vR)
End Sub

or ...
Option Explicit
Sub Split4thdelim()
Dim strOriginal As String
Dim vCounter As Long
Dim vNewElement As String
Dim vCommaCount As Long
strOriginal = "01/01/2020|user1,89|user2,90|user3,99,02/01/2020|user1,80|user2,85|user3,97,03/01/2020|user1,88|user2,96|user3,99"
vNewElement = ""
vCommaCount = 0
For vCounter = 1 To Len(strOriginal)
If Mid$(strOriginal, vCounter, 1) <> "|" And Mid$(strOriginal, vCounter, 1) <> "," Then
vNewElement = vNewElement & Mid$(strOriginal, vCounter, 1)
Else
If Mid$(strOriginal, vCounter, 1) = "|" Then
Debug.Print vNewElement
vNewElement = ""
vCommaCount = 0
ElseIf Mid$(strOriginal, vCounter, 1) = "," Then
vCommaCount = vCommaCount + 1
If vCommaCount = 2 Then
Debug.Print vNewElement
vNewElement = ""
vCommaCount = 0
Else
vNewElement = vNewElement & Mid$(strOriginal, vCounter, 1)
End If
End If
End If
Next
Debug.Print vNewElement
End Sub

Related

Parsing string VBA

please have at look on my issue.
I have following string "F) GND G) FL240)" in my Control.
I'm trying to parse the string between "F)" and "G)" and also between "G)" and ")" with following code
If Left(s, 2) = "F)" Then
'Task - Filled ItemF with value "GND" or other values between "F)" and "G)"
ItemF = Mid(s, InStr(s, "F)") + 3, Len(s) - InStr(s, "G)"))
'or
'ItemF = Mid(s, InStr(s, "F)") + 3, Len(s) - Len(Right(s, InStr(s, "G)"))))
'Task - Filled ItemG with value "FL240" or other values between "G)" and ")"
ItemG = Mid(s, InStr(s, "G)") + 3, Len(s) - InStr(s, "G)")) - how I can exclude last ")"
End If
Could you explain please, how to separate and parse values between "F)" and "G)" and also between "G)" and ")"
Use Split:
FirstValue = Split(Split(s, "F) ")(1), " G)")(0)
SecondValue = Split(Split(s, "G) ")(1), ")")(0)
Use this function -
Public Function fParseXML(sTag01 As String, sTag02 As String, sToParse As String) As String
Dim pStart As Integer
Dim pEnd As Integer
Dim pLen As Integer
If InStr(1, sToParse, sTag01) Then
pStart = InStr(1, sToParse, sTag01) + Len(sTag01)
pEnd = InStr(pStart, sToParse, sTag02)
pLen = pEnd - pStart
fParseXML = Mid(sToParse, pStart, pLen)
Exit Function
Else
fParseXML = "Not found" & "**" & sTag01 & "**" & Mid(sToParse, 1, 100)
Exit Function
End If
use F) and G) and ) as the tags.

Convert text with unicode to HTML entities

In VBA, how do you convert text containing Unicode to HTML entities?
Eg. Test chars: èéâ👍 would be converted to Test chars: èéâ👍
In Excel, characters are stored using Unicode UTF-16. The "Thumbs up" character (👍) corresponds to the Unicode character U+1F44D, encoded as follows:
in UTF-16 (hex) : 0xD83D 0xDC4D (d83ddc4d)
in UTF-16 (decimal) : 55357 , 56397
The following function (and test procedure) should convert as expected:
Sub test()
txt = String2Html("Test chars: èéâ" & ChrW(&HD83D) & ChrW(&HDC4D))
debug.print txt ' -> Test chars: èéâ👍
End Sub
Function String2Html(strText As String) As String
Dim i As Integer
Dim strOut As String
Dim char As String
Dim char2 As String
Dim intCharCode As Integer
Dim intChar2Code As Integer
Dim unicode_cp As Long
For i = 1 To Len(strText)
char = Mid(strText, i, 1)
intCharCode = AscW(char)
If (intCharCode And &HD800) = &HD800 Then
i = i + 1
char2 = Mid(strText, i, 1)
intChar2Code = AscW(char2)
unicode_cp = (intCharCode And &H3FF) * (2 ^ 10) + (intChar2Code And &H3FF)
strOut = strOut & "&#x" & CStr((intCharCode And &H3C0) + 1) & Hex(unicode_cp) & ";"
ElseIf intCharCode > 127 Then
strOut = strOut & "&#x" & Hex(intCharCode) & ";"
ElseIf intCharCode < 0 Then
strOut = strOut & "&#x" & Hex(65536 + intCharCode) & ";"
Else
strOut = strOut & char
End If
Next
String2Html = strOut
End Function
To convert Unicode to Asci (eg:  æ  to   æ)
Public Function UnicodeToAscii(sText As String) As String
Dim x As Long, sAscii As String, ascval As Long
If Len(sText) = 0 Then
Exit Function
End If
sAscii = ""
For x = 1 To Len(sText)
ascval = AscW(Mid(sText, x, 1))
If (ascval < 0) Then
ascval = 65536 + ascval ' http://support.microsoft.com/kb/272138
End If
sAscii = sAscii & "&#" & ascval & ";"
Next
UnicodeToAscii = sAscii
End Function
To convert Asci to Unicode (eg:  æ  to   æ)
Public Function AsciiToUnicode(sText As String) As String
Dim saText() As String, sChar As String
Dim sFinal As String, saFinal() As String
Dim x As Long, lPos As Long
If Len(sText) = 0 Then
Exit Function
End If
saText = Split(sText, ";") 'Unicode Chars are semicolon separated
If UBound(saText) = 0 And InStr(1, sText, "&#") = 0 Then
AsciiToUnicode = sText
Exit Function
End If
ReDim saFinal(UBound(saText))
For x = 0 To UBound(saText)
lPos = InStr(1, saText(x), "&#", vbTextCompare)
If lPos > 0 Then
sChar = Mid$(saText(x), lPos + 2, Len(saText(x)) - (lPos + 1))
If IsNumeric(sChar) Then
If CLng(sChar) > 255 Then
sChar = ChrW$(sChar)
Else
sChar = Chr$(sChar)
End If
End If
saFinal(x) = Left$(saText(x), lPos - 1) & sChar
ElseIf x < UBound(saText) Then
saFinal(x) = saText(x) & ";" 'This Semicolon wasn't a Unicode Character
Else
saFinal(x) = saText(x)
End If
Next
sFinal = Join(saFinal, "")
AsciiToUnicode = sFinal
Erase saText
Erase saFinal
End Function
I hope this would be help someone,
I got this code from here

Improve VBA flexibility to convert VLOOKUP to INDEX/MATCH

After all my searching for code to read in a VLOOKUP formula and converting it to INDEX/MATCH came up empty, I wrote some myself.
However, the code (below) is lacking some of the flexibility I would like, but I can't seem to figure out how to make it work. Specifically, I would like to test each range criterion in the VLOOKUP formula for being an absolute reference or not, i.e. preceded by $, and carry that through to the INDEX/MATCH formula that results. For example, the formula =VLOOKUP(A2,$A$1:B$11,2,FALSE) should convert to =INDEX(B$1:B$11,MATCH(A2,$A1:$A11,0)).
NOTE: This sub depends on two functions (ColumnLetterToNumber and ColumnNumberToLetter). As their names imply they take column letters or numbers and interconvert them. Both these functions are short, simple, and work without problems. However, if anyone believes that the code to one or both of them would be helpful, I would be happy to provide them.
Additionally, any ideas on improving code readability and/or execution efficiency would also be appreciated.
Option Explicit
Public Sub ConvertToIndex()
Dim booLookupType As Boolean
Dim booLeftOfColon As Boolean
Dim booHasRowRef As Boolean
Dim lngStartCol As Long
Dim lngRefCol As Long
Dim lngStart As Long
Dim lngEnd As Long
Dim lngMatchType As Long
Dim lngInt As Long
Dim lngRowRef As Long
Dim strRefCol As String
Dim strOldFormula As String
Dim strNewFormula As String
Dim strLookupCell As String
Dim strValueCol As String
Dim strMatchCol As String
Dim strStartRow As String
Dim strEndRow As String
Dim strCheck As String
Dim strLookupRange As String
Dim strTabRef As String
Dim strSheetRef As String
Dim rngToMod As Range
Dim rngModCell As Range
Set rngToMod = Selection
For Each rngModCell In rngToMod
strOldFormula = rngModCell.Formula
lngStart = InStrRev(strOldFormula, "VLOOKUP(")
If lngStart > 0 Then
lngStart = InStr(lngStart, strOldFormula, "(") + 1
lngEnd = InStr(lngStart, strOldFormula, ",")
strLookupCell = Mid(strOldFormula, lngStart, lngEnd - lngStart)
lngStart = lngEnd + 1
lngEnd = InStr(lngStart, strOldFormula, ",")
strLookupRange = Mid(strOldFormula, lngStart, lngEnd - lngStart)
lngStart = lngEnd + 1
lngEnd = InStr(lngStart, strOldFormula, ",")
lngRefCol = CInt(Mid(strOldFormula, lngStart, lngEnd - lngStart))
lngStart = lngEnd + 1
lngEnd = InStr(lngStart, strOldFormula, ")")
booLookupType = (Mid(strOldFormula, lngStart, lngEnd - lngStart) = "TRUE")
If booLookupType Then
lngMatchType = 1
Else
lngMatchType = 0
End If
booLeftOfColon = True
lngEnd = InStr(1, strLookupRange, "]")
If lngEnd > 0 Then
strSheetRef = Left(strLookupRange, lngEnd)
strLookupRange = Right(strLookupRange, Len(strLookupRange) - lngEnd)
Else
strSheetRef = ""
End If
lngEnd = InStr(1, strLookupRange, "!")
If lngEnd > 0 Then
strTabRef = Left(strLookupRange, lngEnd)
strLookupRange = Right(strLookupRange, Len(strLookupRange) - lngEnd)
Else
strTabRef = ""
End If
For lngInt = 1 To Len(strLookupRange)
strCheck = Mid(strLookupRange, lngInt, 1)
Select Case True
Case strCheck = ":"
booLeftOfColon = False
Case booLeftOfColon
If IsNumeric(strCheck) Then
strStartRow = strStartRow & strCheck
Else
strMatchCol = strMatchCol & strCheck
End If
Case Else
If IsNumeric(strCheck) Then strEndRow = strEndRow & strCheck
End Select
Next lngInt
strMatchCol = Replace(strMatchCol, "$", "")
lngStartCol = ColumnLetterToNumber(strMatchCol)
strValueCol = ColumnNumberToLetter(lngStartCol + lngRefCol - 1)
If Len(strStartRow) > 0 Then strStartRow = "$" & strStartRow
If Len(strEndRow) > 0 Then strEndRow = "$" & strEndRow
strValueCol = strSheetRef & strTabRef & strValueCol & strStartRow & ":" & strValueCol & strEndRow
strMatchCol = strSheetRef & strTabRef & strMatchCol & strStartRow & ":" & strMatchCol & strEndRow
strNewFormula = "=INDEX(" & strValueCol & ",MATCH(" & "$" & strLookupCell & "," & strMatchCol & "," & lngMatchType & "))"
rngModCell.Formula = strNewFormula
End If
Next rngModCell
End Sub
At this time I am not looking for help to take this to the next step of enabling it to process VLOOKUP/HLOOKUP or VLOOKUP/MATCH combination formulas.
To avoid all errors I can think of, you would need to change it to a not so good looking way like this:
Sub changeToIndex()
Dim xText As Boolean
Dim xBrac As Long
Dim VLSep As New Collection
Dim i As Long, t As String
With Selection.Cells(1, 1) 'just for now
'it assumes that there is NEVER a text string which has VLOOKUP like =A1&"mean text with VLOOKUP inside it"
While InStr(1, .Formula, "VLOOKUP", vbTextCompare)
Set VLSep = New Collection
VLSep.Add " " & InStr(1, .Formula, "VLOOKUP", vbTextCompare) + 7
'get the parts
For i = VLSep(1) + 1 To Len(.Formula)
t = Mid(.Formula, i, 1)
If t = """" Then
xText = Not xText
ElseIf Not xText Then 'avoid "(", ")" and "," inside of the string to be count
If t = "(" Then
xBrac = xBrac + 1
ElseIf xBrac Then 'cover up if inside of other functions
If t = ")" Then xBrac = xBrac - 1
ElseIf t = ")" Then
VLSep.Add " " & i
Exit For
ElseIf t = "," Then
VLSep.Add " " & i 'the space is to avoid errors with index and item if both are numbers
End If
End If
Next
Dim xFind As String 'get all the parts
Dim xRng As String
Dim xCol As String
Dim xType As String
xFind = Mid(.Formula, VLSep(1) + 1, VLSep(2) - VLSep(1) - 1)
xRng = Mid(.Formula, VLSep(2) + 1, VLSep(3) - VLSep(2) - 1)
xCol = Mid(.Formula, VLSep(3) + 1, VLSep(4) - VLSep(3) - 1)
If VLSep.Count = 5 Then
xType = Mid(.Formula, VLSep(4) + 1, VLSep(5) - VLSep(4) - 1)
Else
xType = "0"
End If
Dim fullFormulaNew As String 'get the whole formulas
Dim fullFormulaOld As String
fullFormulaNew = "INDEX(" & xRng & ",MATCH(" & xFind & ",INDEX(" & xRng & ",,1)," & xType & ")," & xCol & ")"
fullFormulaOld = Mid(Selection.Cells(1, 1).Formula, VLSep(1) - 7, VLSep(VLSep.Count) - VLSep(1) + 8)
.Formula = Replace(.Formula, fullFormulaOld, fullFormulaNew) 'simply replace the old one with the new one
Wend
End With
End Sub
It also should work for very complex formulas. Still you would need some special checks to cut everything so it looks like you want. I just assumed that the range for the vlookup may be something like IF(A1=1,B1:C10,L5:N30) and this said, you would need additional subs to also clear something like this up. :(
A formula like
=VLOOKUP(VLOOKUP(IF(TRUE,A2,"aaa"),$A$1:B$11,2),$B$1:$C$11,2,FALSE)
will be changed (messed up) this way to
=INDEX($B$1:$C$11,MATCH(INDEX($A$1:B$11,MATCH(IF(TRUE,A2,"aaa"),INDEX($A$1:B$11,,1),0),2),INDEX($B$1:$C$11,,1),FALSE),2)
EDIT
Assuming your formulas are "normal" you can replace the the last part with:
Dim xFind As String 'get all the parts
Dim xRngI As String, xRngM As String
Dim xCol As String
Dim xType As String
xFind = Mid(.Formula, VLSep(1) + 1, VLSep(2) - VLSep(1) - 1)
xRngI = Mid(.Formula, VLSep(2) + 1, VLSep(3) - VLSep(2) - 1)
xCol = Mid(.Formula, VLSep(3) + 1, VLSep(4) - VLSep(3) - 1)
If VLSep.Count = 5 Then
xType = Mid(.Formula, VLSep(4) + 1, VLSep(5) - VLSep(4) - 1)
Else
xType = "0"
End If
If xType = "FALSE" Then xType = 0
Do While Not IsNumeric(xCol)
Select Case MsgBox("Error: The Column to pick from is not numerical! Do you want to manually set the column (Yes) or directly use the last column of the input range (No)?", vbYesNoCancel)
Case vbYes
xCol = Application.InputBox("Input the column number for the input range (" & xRngI & "). '1' will be the range " & Range(xRngI).Columns(1).Address(0, 0) & ".", "Column to pick from", 1, , , , , 2)
Case vbNo
xCol = Range(xRngI).Columns.Count
Case vbCancel
xCol = " "
Exit Do
End Select
If xCol <> CInt(xCol) Or xCol > Range(xRngI).Columns.Count Or xCol = 0 Then xCol = " "
Loop
If IsNumeric(xCol) Then
Dim absRs As Boolean, absRe As Boolean, absCs As Boolean, absCe As Boolean
absCs = (Left(xRngI, 1) = "$")
absCe = (Mid(xRngI, InStr(xRngI, ":") + 1, 1) = "$")
absRs = (InStr(2, Left(xRngI, InStr(xRngI, ":") - 1), "$") > 0)
absRe = (InStr(Mid(xRngI, InStr(xRngI, ":") + 2), "$") > 0)
xRngM = Range(xRngI).Columns(1).Cells(1, 1).Address(absRs, absCs) & ":" & Range(xRngI).Columns(1).Cells(Range(xRngI).Rows.Count, 1).Address(absRe, absCs) 'for MATCH
xRngI = Range(xRngI).Cells(1, CLng(xCol)).Address(absRs, absCe) & ":" & Range(xRngI).Cells(Range(xRngI).Rows.Count, CLng(xCol)).Address(absRe, absCe) 'for INDEX
Dim fullFormulaNew As String, fullFormulaOld As String
fullFormulaNew = "INDEX(" & xRngI & ",MATCH(" & xFind & "," & xRngM & "," & xType & "))"
fullFormulaOld = Mid(Selection.Cells(1, 1).Formula, VLSep(1) - 7, VLSep(VLSep.Count) - VLSep(1) + 8)
.Formula = Replace(.Formula, fullFormulaOld, fullFormulaNew) 'simply replace the old one with the new one
End If
Wend
End With
End Sub
As you can see: the "simpler" the outcome, the more code you need. If the lookup_range is not just a address, this will fail.
If you still have any questions, just ask ;)

Edit a CSV in vb

i have a CSV export from a earlier version of a software and would like to import it into the new version but however I would only like a couple of columns from the CSV and for it to display when I click button1 in a windows form in col order. Can this be done and how.
please message if don't understand and will go into more details.
i have this so far but this just displays the CSV
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim dx As Long = 0
Dim dRow As Long = 0
Dim dColumn As Long = 0
Dim dTotalRows As Long = 0
Dim dTotalColumns As Long = 0
Dim dFileName As String = ""
Dim dReadLine As String = ""
Dim dChar As String = ""
Dim dArray(1, 1) As String
Dim dStart As Long = 1
Dim dEnd As Long = 1
Dim dLen As Long = 0
Dim dLineLength As Long = 0
Dim dQuoteCounter As Long = 0
Dim dAdd2ItemList As String = ""
dFileName = "E:\test docs/test.csv"
FileOpen(1, dFileName, OpenMode.Input, OpenAccess.Default, OpenShare.Default, -1)
Do While Not EOF(1)
dReadLine = LineInput(1)
dRow = dRow + 1
dTotalColumns = dColumn
dColumn = 0
dLineLength = Len(dReadLine)
For dx = 1 To dLineLength
dChar = Mid(dReadLine, dx, 1)
If dChar = Chr(34) Then
dQuoteCounter = dQuoteCounter + 1
If dQuoteCounter = 2 * (Int(dQuoteCounter / 2)) Then
dChar = Mid(dReadLine, dx, 2)
If dChar = Chr(34) + "," Then
dColumn = dColumn + 1
dQuoteCounter = -1
If Chr(34) = dChar + "," Then
dQuoteCounter = -1
dColumn = dColumn + 1
End If
End If
End If
End If
If dQuoteCounter = 0 And dChar = "," Then
dColumn = dColumn + 1
End If
If dx = dLineLength Then
dColumn = dColumn + 1
End If
If dQuoteCounter = -1 And dChar = "," Then dQuoteCounter = 0
Next (dx)
Loop
dTotalRows = dRow
ReDim dArray(dTotalRows, dTotalColumns)
FileClose(1)
dRow = 0
FileOpen(1, dFileName, OpenMode.Input, OpenAccess.Default, OpenShare.Default, -1)
Do While Not EOF(1)
dAdd2ItemList = ""
dRow = dRow + 1
dStart = 1
dEnd = 1
dLen = 0
dColumn = 0
dReadLine = LineInput(1)
dLineLength = Len(dReadLine)
For dx = 1 To dLineLength
dChar = Mid(dReadLine, dx, 1)
If dChar = Chr(34) Then
dQuoteCounter = dQuoteCounter + 1
If dQuoteCounter = 1 Then dStart = dx + 1
If dQuoteCounter = 2 * (Int(dQuoteCounter / 2)) Then
dChar = Mid(dReadLine, dx, 2)
If dChar = Chr(34) + "," Then
dEnd = dx
dLen = dEnd - dStart
dColumn = dColumn + 1
dArray(dRow, dColumn) = Mid(dReadLine, dStart, dLen)
dAdd2ItemList = dAdd2ItemList + dArray(dRow, dColumn) + "|"
dQuoteCounter = -1
dStart = dx + 2
End If
End If
End If
If dQuoteCounter = 0 And dChar = "," Then
dEnd = dx
dLen = (dEnd - dStart)
dColumn = dColumn + 1
If dLen < 1 Then
dArray(dRow, dColumn) = ""
dAdd2ItemList = dAdd2ItemList + dArray(dRow, dColumn) + "|"
Else
dArray(dRow, dColumn) = Mid(dReadLine, dStart, dLen)
dAdd2ItemList = dAdd2ItemList + dArray(dRow, dColumn) + "|"
End If
dStart = dx + 1
End If
If dx = dLineLength Then
dEnd = dx
dLen = (dEnd - dStart) + 1
dColumn = dColumn + 1
If dLen < 1 Then
dArray(dRow, dColumn) = ""
dAdd2ItemList = dAdd2ItemList + dArray(dRow, dColumn)
Else
dArray(dRow, dColumn) = Mid(dReadLine, dStart, dLen)
dAdd2ItemList = dAdd2ItemList + dArray(dRow, dColumn)
End If
dStart = dx + 1
End If
If dQuoteCounter = -1 And dChar = "," Then dQuoteCounter = 0
Next (dx)
ListBox1.Items.Add(dAdd2ItemList)
REM dRow = dRow + 1
Loop
End Sub
End Class

Setting a delimiter to generate an export

I found a VBA code that almost fits my requirements to export data to a CSV file. I am having problems with the delimiter function.
I have the following function:
Function DelimitRange(ByVal XLArray As Variant) As String
Const delimiter As String = ","
Const lineFeed As String = vbCrLf
Const removeExisitingDelimiter As Boolean = True
Dim rowCount As Long
Dim colCount As Long
Dim tempString As String
For rowCount = LBound(XLArray, 1) To UBound(XLArray, 1)
For colCount = LBound(XLArray, 2) To UBound(XLArray, 2)
If removeExisitingDelimiter Then
tempString = tempString & Replace(XLArray(rowCount, colCount), delimiter, vbNullString)
Else
tempString = tempString & XLArray(rowCount, colCount)
End If
'Don't add delimiter to column end
If colCount < UBound(XLArray, 2) Then tempString = tempString & delimiter
Next colCount
'Add linefeed
If rowCount < UBound(XLArray, 1) Then tempString = tempString & lineFeed
Next rowCount
DelimitRange = tempString
End Function
This code is generating me something like that:
a,,,
d,,z,
uo,,,
u,,c,
h,,,
I need this function to generate the line skipping extra commas when there is no more characters to display at the end of each line.
I need this function to give me the following output (using the same data as the example given before:
a
d,,z
uo
u,,c
h
Thanks in advance for your help.
Please see the usage of currentItem in the code. Modify your code according to the code below.
dim currentItem as string
dim lastNonBlankIndex as Integer
dim dataForTheRow
dim stringifiedRow as string
For rowCount = LBound(XLArray, 1) To UBound(XLArray, 1)
redim dataForTheRow(LBound(XLArray, 2) To UBound(XLArray, 2))
lastNonBlankIndex = LBound(XLArray, 2)
For colCount = LBound(XLArray, 2) To UBound(XLArray, 2)
If removeExisitingDelimiter Then
currentItem = Replace(XLArray(rowCount, colCount), delimiter, vbNullString)
Else
currentItem = XLArray(rowCount, colCount)
End If
dataForTheRow(colCount) = currentItem
If Trim(currentItem) <> "" Then
lastNonBlankIndex = colCount
End If
Next colCount
redim preserve dataForTheRow(LBound(XLArray, 2) To lastNonBlankIndex)
stringifiedRow = Join(dataForTheRow, delimiter)
Debug.Print stringifiedRow
'Add linefeed
tempString = tempString & stringifiedRow
If rowCount < UBound(XLArray, 1) Then
tempString = tempString & lineFeed
End If
Next rowCount
Store the delimiters in delimitList and concatenate them only if some other element appears in the same row.
Please see the full code below:
Function DelimitRange(ByVal XLArray As Variant) As String
Const delimiter As String = ","
Const lineFeed As String = vbCrLf
Const removeExisitingDelimiter As Boolean = True
Dim rowCount As Long
Dim colCount As Long
Dim tempString As String
Dim delimitList As String
Dim currentItem As String
Dim tempSubString As String
For rowCount = LBound(XLArray, 1) To UBound(XLArray, 1)
delimitList = ""
For colCount = LBound(XLArray, 2) To UBound(XLArray, 2)
currentItem = XLArray(rowCount, colCount)
If Trim(currentItem) <> "" Then
If tempSubString <> "" Then tempSubString = tempSubString & delimiter
tempSubString = tempSubString & delimitList
If removeExisitingDelimiter Then
tempSubString = tempSubString & Replace(currentItem, delimiter, vbNullString)
Else
tempSubString = tempSubString & currentItem
End If
delimitList = ""
Else
delimitList = delimitList & delimiter
End If
Next colCount
tempString = tempString & tempSubString
tempSubString = ""
'Add linefeed
If rowCount < UBound(XLArray, 1) Then tempString = tempString & lineFeed
Next rowCount
DelimitRange = tempString
End Function
Line feed change:
'Add linefeed
If rowCount < UBound(XLArray, 1) Then
While tempString Like "*" & delimiter
tempString=left(tempString, Len(tempstring)-len(delimiter))
Wend
tempString = tempString & lineFeed
End if