Generate XML File with VBA - excel

I'm trying to generate an XML file with VBA code.
My goal is to alter Excel data, and then to export this data into a valid XML file. There's only one row of data and one row for the name of the tags which I want to have the data inside.
How can I run through all the data and generate an XML file?
Some sample data (My original file has more columns and data).
(The yellow data is my first block in XML and the green data my second block.)
Here's how the XML File should look:
<?xml version="1.0" encoding="UTF-8"?>
<NmLoader>
<csvBeginTypeDefView handler ="TypeDefinition">
<csvattTemplate>LW</csvattTemplate>
<csvnameSpace>default</csvnameSpace>
<csvname>Tires</csvname>
<csvcontainerDomain/>
<csvtypeParent>Wheels</csvtypeParent>
</csvBeginTypeDefView>
<csvBeginAttributeDefView handler = "AttributeDefinition">
<csvname>TiresAT</csvname>
<csvattDefClass>Definition</csvattDefClass>
<csvdatatype>String</csvdatatype>
<csvIBA>TiresAT</csvIBA>
<csvQoM/>
</csvBeginAttributeDefView>
</NmLoader>
My Code:
Public Sub GenerateXML()
Dim sht As Worksheet
Dim loLetzteZ As Long, loLetzteS As Long, i As Long
Dim rBereich As Range, rng As Range
Dim sTagO As String, sTagC As String, sTagOEnd As String, sTagCStart As String
Dim sZeile As String
Dim strPfad As String
Dim strText As String
sTagO = "<"
sTagOEnd = "/>"
sTagC = ">"
sTagCStart = "</"
Set sht = Worksheets("Data")
'determine the last possible row
loLetzteZ = sht.Cells(Rows.Count, 1).End(xlUp).Row
'determine the last possible column
loLetzteS = sht.Cells(1, Columns.Count).End(xlToLeft).Column
'set me the area for the complete worksheet
Set rBereich = sht.Range("A2:" & Cells(loLetzteZ, loLetzteS).Address)
Application.ScreenUpdating = False
strPfad = ActiveWorkbook.Path & "\Data" & ".xml"
'row for row
For Each rng In rBereich.Rows
With rng
'column for column
For i = 1 To .Columns.Count
'If the tag is empty, then close this
If IsEmpty(.Cells(1, i)) Then
sZeile = sZeile & sTagO & Cells(1, i) & sTagOEnd
Else
'Opening Tag
sZeile = sZeile & sTagO & Cells(1, i) & sTagC
'Data for the tags
sZeile = sZeile & .Cells(1, i)
'End of Tags
sZeile = sZeile & sTagCStart & Cells(1, i) & sTagC
End If
'Write line with distance
sZeile = sZeile & vbCrLf
Next
'Write line with distance
sZeile = sZeile & vbCrLf & vbCrLf
'Open file and write the text
Call InDateiSchreiben(strPfad, sZeile, True)
End With
Next
Application.ScreenUpdating = True
End Sub
Other Solutions I tried:
I've already mapped the XML with Excel, but Excel is not able to export such an XML Schema.
I wrote code in VBA (I'm a beginner) by looking through posts regarding an XML Export.

Try this
Function GetXmlElement(sTagName As String, _
sValue As String, _
Optional bUseEmptyTags As Boolean = False, _
Optional bMultiline As Boolean = False) As String
Dim sStartOpen As String: sStartOpen = "<"
Dim sClose As String: sClose = ">"
Dim sEndOpen As String: sEndOpen = "</"
Dim sEmptyClose As String: sEmptyClose = " />"
Dim sTab As String: sTab = " "
Dim sTagValSeparator As String
Dim sValTagSeparator As String
If bMultiline Then
sTagValSeparator = Chr(10) & sTab
sValTagSeparator = Chr(10)
End If
If Len(sValue) = 0 And bUseEmptyTags Then
GetXmlElement = sStartOpen & sTagName & sEmptyClose
Else
GetXmlElement = sStartOpen & sTagName & sClose & sTagValSeparator & _
Replace(sValue, Chr(10), Chr(10) & sTab) & _
sValTagSeparator
If InStr(1, sTagName, " ") > 0 Then
'tag has attributes'
sTagName = Left(sTagName, InStr(1, sTagName, " ") - 1)
End If
GetXmlElement = GetXmlElement & sEndOpen & sTagName & sClose
End If
End Function
Function GetXMLOutput() As String
Dim lLastCol As Long
Dim i As Long
Dim lCsvBeginCol As Long
Dim sTagName As String
Dim sInnerElements As String
Dim sOutput As String
With ThisWorkbook.Sheets("Data")
lLastCol = .Cells(1, Columns.Count).End(xlToLeft).Column
lCsvBeginCol = 1
For i = 1 To lLastCol
sTagName = .Cells(1, i)
If Left(sTagName, 8) = "csvBegin" And i > lCsvBeginCol Or i = lLastCol Then
' build the outer element
sTagName = .Cells(1, lCsvBeginCol) & "=""" & .Cells(2, lCsvBeginCol) & """"
If Len(sOutput) > 0 Then
sOutput = sOutput & Chr(10) & Chr(10)
End If
sOutput = sOutput & GetXmlElement(sTagName, sInnerElements, True, True)
lCsvBeginCol = i
sInnerElements = ""
ElseIf i <> lCsvBeginCol Then
' build the inner elements
If Len(sInnerElements) > 0 Then sInnerElements = sInnerElements & Chr(10)
sInnerElements = sInnerElements & GetXmlElement(sTagName, .Cells(2, i), True)
End If
Next i
sOutput = GetXmlElement("NmLoader", sOutput, True, True)
sOutput = "<?xml version=""1.0"" encoding=""UTF-8""?>" & Chr(10) & Chr(10) & sOutput
GetXMLOutput = sOutput
Debug.Print sOutput
End With
End Function
Sub GenerateXML()
Dim sFilename As String
sFilename = ThisWorkbook.Path & "\Data.xml"
Open sFilename For Output As #1
Print #1, GetXMLOutput
Close #1
End Sub

Try
Option Explicit
Public Sub GenerateXML()
Dim sht As Worksheet
Set sht = Worksheets("Data")
Dim loLetzteZ As Long, loLetzteS As Long, i As Long
Dim rBereich As Range, rng As Range
Dim sZeile As String
Dim strPfad As String
Dim sTag As String, sTag1 As String, sData As String
'determine the last possible row
loLetzteZ = sht.Cells(Rows.Count, 1).End(xlUp).Row
'determine the last possible column
loLetzteS = sht.Cells(1, Columns.Count).End(xlToLeft).Column
'set me the area for the complete worksheet
Set rBereich = sht.Range("A2:" & Cells(loLetzteZ, loLetzteS).Address)
' output
strPfad = ActiveWorkbook.Path & "\Data" & ".xml"
sTag1 = ""
sZeile = "<?xml version=""1.0"" encoding=""UTF-8""?>" & vbCrLf _
& "<NmLoader>" & vbCrLf
'row for row
For Each rng In rBereich.Rows
With rng
'column for column
For i = 1 To .Columns.Count
sTag = Trim(sht.Cells(1, i))
sData = Trim(.Cells(1, i))
'If the tag is handler
If LCase(Right(sTag, 7)) = "handler" Then
sTag1 = Split(sTag, " ")(0) ' remove handler
sZeile = sZeile & "<" & sTag1 & " handler=""" & sData & """>"
' is it a closing tag
ElseIf sTag = sTag1 Then
sZeile = sZeile & "</" & sTag1 & ">" & vbCrLf
ElseIf Len(sData) > 0 Then
sZeile = sZeile & vbTab & "<" & sTag & ">" & sData & "</" & sTag & ">"
Else
sZeile = sZeile & vbTab & "<" & sTag & "/>"
End If
sZeile = sZeile & vbCrLf
Next
'Write line with distance
sZeile = sZeile & vbCrLf & "</NmLoader>" & vbCrLf
'Open file and write the text
Debug.Print sZeile
'Call InDateiSchreiben(strPfad, sZeile, True)
End With
Next
MsgBox strPfad & " created", vbInformation
End Sub

Related

Delimiter in VBA,Macros

Need to split the 3rd row and have it in the below xml format.
My Excel data:
ID
EMail
UserGroupID
Aravind
Aravind#gmail.com
Sports(12-34)
Aravind2
Aravind2#gmail.com
Sports(3-24-5),Health(5-675-85), Education(57-85-96)
My XML data:
<?xml version="1.0" encoding="utf-8"?>
<Core-data ContextID="Context1" WorkspaceID="Main">
<UserList>
<User ID="Aravind" ForceAuthentication="false" Password="1234" EMail="Aravind#gmail.com">
<Name>Aravind</Name>
<UserGroupLink UserGroupID="12-34"/>
</User>
<User ID="Aravind2" ForceAuthentication="false" Password="1234" EMail="Aravind#gmail.com">
<Name>Aravind2</Name>
<UserGroupLink UserGroupID="3-24-5"/>
<UserGroupLink UserGroupID="5-675-85"/>
<UserGroupLink UserGroupID="57-85-96"/>
</User>
</UserList>
</Core-data>
The code Im using:(Need change in delimiting the 3 rd row & location only)
Sub Generate_xml()
Const FOLDER = "C:\Temp\"
Const XLS_FILE = "UserDataEntry.xlsm"
Const XML_FILE = "User XML.xml"
Const XML = "<?xml version=""1.0"" encoding=""utf-8""?>" & vbCrLf & _
"<Core-data ContextID=""Context1"" WorkspaceID=""Main"">" & vbCrLf & _
" <UserList>" & vbCrLf
Dim wb As Workbook, ws As Worksheet, ar, s As String
Dim iLastRow As Long, r As Long, n As Integer
' open source workbook
Set wb = Workbooks.Open(FOLDER & XLS_FILE, 1, 1)
Set ws = wb.Sheets("Sheet1")
iLastRow = ws.Cells(Rows.Count, "A").End(xlUp).Row
' create XML document
'<User ID="Aravind" ForceAuthentication="false" Password="1234" EMail="Aravind#gmail.com.com">
' <Name>Aravind</Name>
' <UserGroupLink UserGroupID="Sports"/>
'</User>
s = XML
For r = 2 To iLastRow
s = s & " <User ID=""" & ws.Cells(r, 1) & """" & _
" ForceAuthentication=""false"" Password=""1234""" & _
" EMail=""" & ws.Cells(r, 2) & """>" & vbCrLf
s = s & " <Name>" & ws.Cells(r, 1) & "</Name>" & vbCrLf
ar = Split(ws.Cells(r, 3), ",")
For n = LBound(ar) To UBound(ar)
s = s & " <UserGroupLink UserGroupID=""" & Trim(ar(n)) & """/>" & vbCrLf
Next
s = s & " </User>" & vbCrLf
Next
s = s & " </UserList>" & vbCrLf & "</Core-data>"
' save
Dim fso, ts
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.createtextfile(FOLDER & XML_FILE)
ts.write s
ts.Close
MsgBox "Xml created to " & FOLDER & XML_FILE
End Sub
Is there is any way to run this VBA code in any location and the XML generated to be in same location.
Kindly share your inputs & thanks in advance.
Try something like this:
Sub Generate_xml()
Const FOLDER = "C:\Temp\"
Const XLS_FILE = "UserDataEntry.xlsm"
Const XML_FILE = "User XML.xml"
Const XML = "<?xml version=""1.0"" encoding=""utf-8""?>" & vbCrLf & _
"<Core-data ContextID=""Context1"" WorkspaceID=""Main"">" & vbCrLf & _
" <UserList>" & vbCrLf
Dim wb As Workbook, ws As Worksheet, s As String, savePath As String
Dim r As Long, e
' open source workbook
Set wb = Workbooks.Open(FOLDER & XLS_FILE, 1, 1)
Set ws = wb.Sheets("Sheet1")
' create XML document
s = XML
For r = 2 To ws.Cells(Rows.Count, "A").End(xlUp).Row
s = s & " <User ID=""" & ws.Cells(r, 1) & """" & _
" ForceAuthentication=""false"" Password=""1234""" & _
" EMail=""" & ws.Cells(r, 2) & """>" & vbCrLf
s = s & " <Name>" & ws.Cells(r, 1) & "</Name>" & vbCrLf
For Each e In TextInParentheses(ws.Cells(r, 3).Value)
s = s & " <UserGroupLink UserGroupID=""" & Trim(e) & """/>" & vbCrLf
Next e
s = s & " </User>" & vbCrLf
Next
s = s & " </UserList>" & vbCrLf & "</Core-data>"
'wb.Close false 'close source workbook
' save to same path as running code
savePath = ThisWorkbook.Path & "\" & XML_FILE
PutContent savePath, s
MsgBox "Xml created at '" & savePath & "'", vbInformation
End Sub
'all texts enclosed in parentheses as a collection
Function TextInParentheses(txt As String)
Dim re As Object
Dim allMatches, m, col As New Collection
Set re = CreateObject("VBScript.RegExp")
re.Pattern = "\(([^\)]+)\)"
re.ignorecase = True
re.Global = True
Set allMatches = re.Execute(txt)
For Each m In allMatches
col.Add Trim(m.submatches(0))
Next m
Set TextInParentheses = col
End Function
'Save text `content` to a text file at `f`
Sub PutContent(f As String, content As String)
CreateObject("scripting.filesystemobject"). _
opentextfile(f, 2, True).write content
End Sub

Excel Data to XML

Need to convert excel data into XML format.
'vba code to convert excel to xml
Sub vba_code_to_convert_excel_to_xml()
Set wb = Workbooks.Open("C:\temp\testwb.xlsx")
wb.SaveAs fileName:="C:\temp\testX.xml", FileFormat:= _
xlXMLSpreadsheet, ReadOnlyRecommended:=False, CreateBackup:=False
Kindly let me how to do this in VBA or provide a link where I can refer. Thanks in Advance.
For a simple case one way would be to build the xml line by line
Sub vba_code_to_convert_excel_to_xml2()
Const FOLDER = "C:\temp\"
Const XLS_FILE = "testwb.xlsx"
Const XML_FILE = "testX.xml"
Const XML = "<?xml version=""1.0"" encoding=""utf-8""?>" & vbCrLf & _
"<Core-Information ContextID=""Context1"" WorkspaceID=""Main"">" & vbCrLf & _
" <UserList>" & vbCrLf
Dim wb As Workbook, ws As Worksheet, ar, s As String
Dim iLastRow As Long, r As Long, n As Integer
' open source workbook
Set wb = Workbooks.Open(FOLDER & XLS_FILE, 1, 1)
Set ws = wb.Sheets("Sheet1")
iLastRow = ws.Cells(Rows.Count, "A").End(xlUp).Row
' create XML document
'<User ID="Aravind" ForceAuthentication="false" Password="1234" EMail="Aravind#gmail.com">
' <Name>Aravind</Name>
' <UserGroupLink UserGroupID="Sports"/>
'</User>
s = XML
For r = 2 To iLastRow
s = s & " <User ID=""" & ws.Cells(r, 1) & """" & _
" ForceAuthentication=""false"" Password=""" & ws.Cells(r, 2) & """" & _
" EMail=""" & ws.Cells(r, 3) & """>" & vbCrLf
s = s & " <Name>" & ws.Cells(r, 1) & "</Name>" & vbCrLf
ar = Split(ws.Cells(r, 4), ",")
For n = LBound(ar) To UBound(ar)
s = s & " <UserGroupLink UserGroupID=""" & Trim(ar(n)) & """/>" & vbCrLf
Next
s = s & " </User>" & vbCrLf
Next
s = s & " </UserList>" & vbCrLf & "</Core-Information>"
' save
Dim fso, ts
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.createtextfile(FOLDER & XML_FILE)
ts.write s
ts.Close
MsgBox "Xml created to " & FOLDER & XML_FILE
End Sub

Loop through cells of all Excel Worksheets to generate one XML file

I have 10 sheets. I wrote some code to go through all the data inside a sheet and create an XML file as an output.
I have to click the button each time at each sheet and then I have 10 different XML files. I want one button in one sheet, let's call it Description, to go through all my sheets and create one file with all the XML data.
I tried to use a for each loop. Instead of reading all the sheets, it reads only the first sheet for many times.
Sub XMLTextdatei()
Dim sht As Worksheet
Dim loLetzteZ As Long, loLetzteS As Long, I As Long
Dim rBereich As Range, rng As Range
Dim sTagO As String, sTagC As String, sTagOEnd As String, sTagCStart As String
Dim sZeile As String
Dim strPfad As String
Dim strText As String
sTagO = "<"
sTagOEnd = "/>"
sTagC = ">"
sTagCStart = "</"
Set sht = ActiveSheet
For Each sht In Worksheets
loLetzteZ = sht.Cells(Rows.Count, 1).End(xlUp).Row
loLetzteS = sht.Cells(1, Columns.Count).End(xlToLeft).Column
Set rBereich = sht.Range("A2:" & Cells(loLetzteZ, loLetzteS).Address)
Application.ScreenUpdating = False
sZeile = ""
strPfad = ActiveWorkbook.Path & "\Classification" & "_" & Format(Time, "hhmmss") & ".xml"
'zeile für zeile
For Each rng In rBereich.Rows
With rng
'spalte für spalte
For I = 1 To .Columns.Count
If I = 1 Then
sZeile = sZeile & sTagO & Cells(1, I) & "=""" & .Cells(1, I) & """" & sTagC
Else
If IsEmpty(.Cells(1, I)) Then
sZeile = sZeile & sTagO & Cells(1, I) & sTagOEnd
Else
sZeile = sZeile & sTagO & Cells(1, I) & sTagC
sZeile = sZeile & .Cells(1, I)
sZeile = sZeile & sTagCStart & Cells(1, I) & sTagC
End If
End If
sZeile = sZeile & vbCrLf
Next
'sZeile = sZeile & "</" & " " & ">"
sZeile = sZeile & vbCrLf & vbCrLf
Call InDateiSchreiben(strPfad, sZeile, True)
sZeile = ""
End With
Next
Next
Application.ScreenUpdating = True
End Sub
This will traverse all worksheets. You need to use your sheet variable in the loop, instead of just setting it outside the loop
Dim oCurSheet As Worksheet
For Each oCurSheet In Me.Worksheets
oCurSheet.(Whatever you are doing with it)
Next
Edit:
I've gotten rid of rBereich in the for each collection in favor of going to the sheet. Also removed setting sht to active sheet, as the assigning is done in the for loop.
You need to use the variables in your for each loops where applicable within the loops. In the updated code you'll see sht.Cells(1,I) used to reference the current Sheet's Columns.
The additional Empty tags were due to your If IsEmpty statement, if there was nothing in the tag you were adding < (blank) </>. So I've commented the line out, if you need a value to illustrate blanks then you would want to do it simlar to the else statement, and put a value say NA where the .cells(1,I) is.
Dim sht As Worksheet
Dim loLetzteZ As Long, loLetzteS As Long, I As Long
Dim rng As Range
Dim sTagO As String, sTagC As String, sTagOEnd As String, sTagCStart As String
Dim sZeile As String
Dim strPfad As String
Dim strText As String
sTagO = "<"
sTagOEnd = "/>"
sTagC = ">"
sTagCStart = "</"
For Each sht In Me.Worksheets
loLetzteZ = sht.Cells(Rows.Count, 1).End(xlUp).Row
loLetzteS = sht.Cells(1, Columns.Count).End(xlToLeft).Column
For Each rng In sht.Range("A2:" & sht.Cells(loLetzteZ, loLetzteS).Address).Rows
Application.ScreenUpdating = False
sZeile = ""
strPfad = ActiveWorkbook.Path & "\Classification" & "_" & Format(Time, "hhmmss") & ".xml"
With rng
'spalte für spalte
For I = 1 To .Columns.Count
If I = 1 Then
sZeile = sZeile & sTagO & sht.Cells(1, I) & "=""" & .Cells(1, I) & """" & sTagC
Else
If IsEmpty(.Cells(1, I)) Then
' No Tag if empty
'sZeile = sZeile & sTagO & sht.Cells(1, I) & sTagOEnd
Else
sZeile = sZeile & sTagO & sht.Cells(1, I) & sTagC
sZeile = sZeile & .Cells(1, I)
sZeile = sZeile & sTagCStart & sht.Cells(1, I) & sTagC
End If
End If
sZeile = sZeile & vbCrLf
Next
'sZeile = sZeile & "</" & " " & ">"
sZeile = sZeile & vbCrLf & vbCrLf
'MsgBox (sZeile)
Call InDateiSchreiben(strPfad, sZeile, True)
sZeile = ""
End With
Next
Next
Application.ScreenUpdating = True
Why not using the save as XML of Excel ?
You could use use your code to reunite the data into a new sheet and then use the saveas xml format.
If you use the xml 2003 you do not need to set any xml mapping, for higher versions allow you to create your own XML mapping (see developper ruler).

copy sheet to text file with specific template skips even numbers

I want to copy sheet to text file with specific template, I defined a range but the problem is it skips even numbers it means rows A2, A4,A6... not copied
so it brings at the end of the result empty rows
Option Explicit
Sub txtFile()
Dim strPath As String
Dim fso As Object
Dim ts As Object
Dim wsDest As Worksheet
Set wsDest = Sheets("Filter FS")
wsDest.Select
Set fso = CreateObject("Scripting.FileSystemObject")
Dim cellAimsID As Variant
Dim cellAmount As Variant
Dim cellCurrencyISO As Variant
Dim cellReason As Variant
Dim cellExpiryDate As Variant
Dim FirstRow As String
Dim LastRow As String
Dim a As Range, b As Range, cell As String, rng As Range
Set a = Selection
Set ts = fso.CreateTextFile("C:\Users\cben\Documents\BKC\FinancialSecurity\test13.txt", True, True)
' for each cell in the worksheet create a line in text fil
FirstRow = wsDest.UsedRange.Rows(1).Row
LastRow = wsDest.Range("A" & Rows.Count).End(xlUp).Row
Set rng = wsDest.Range("A2:A" & LastRow)
'Set rng = wsDest.Range("A1:A5")
For Each a In rng
cellAimsID = a.Cells(a.Row, 1)
cellAmount = a.Cells(a.Row, 2)
cellCurrencyISO = a.Cells(a.Row, 3)
cellReason = a.Cells(a.Row, 4)
cellExpiryDate = a.Cells(a.Row, 5)
'AimsID, Amount, Currency, Reason, ExpiryDate are the name of columns in worksheet
ts.WriteLine (Chr(9) & "cases" & ": [")
ts.WriteLine (Chr(9) & "{")
ts.WriteLine (Chr(9) & "AimsID:" & cellAimsID & ",")
ts.WriteLine (Chr(9) & "Amount:" & cellAmount & ",")
ts.WriteLine (Chr(9) & "CurrencyISO:" & cellCurrencyISO & ",")
ts.WriteLine (Chr(9) & "Reason:" & cellReason & ",")
ts.WriteLine (Chr(9) & "ExpiryDate:" & cellExpiryDate & ",")
ts.WriteLine (Chr(9) & "}" & ",")
Next
ts.Close
End Sub
here is the result
for exemple AimsID= 69210794 correspond to A41 next AimsID =86917526 corresponds to A43 not A42 in the result
The problem lies in your For Each loop as detailed below.
For Each a In rng
cellAimsID = a.Cells(a.Row, 1)
cellAmount = a.Cells(a.Row, 2)
cellCurrencyISO = a.Cells(a.Row, 3)
cellReason = a.Cells(a.Row, 4)
cellExpiryDate = a.Cells(a.Row, 5)
In this loop, the variable a refers to a Range object. Yet, inside of the loop, you assign to each variable a Range property of a Range object. Let's take a closer look as an example:
`cellAimsID = a.Cells(a.Row, 1)
Let's assume you are on the second iteration of the loop, and the variable a refers to cell A3. The syntax above says cellsAimsID = Range("A3").Range("A3"). What happens when we apply a Range property to a Range object? It basically offsets cell. In that above example, the cell pointer essentially moves to a cell that would be the third cell in Column A IF the range started with A3.
I know that sounds a bit confusing, but follow up if you have questions.
To fix the error, replace the syntax with (notice I removed the a qualifier):
cellAimsID = Cells(a.Row, 1)
cellAimsID = Cells(a.Row, 1)
As a side note, it is a good practice to fully qualify your ranges with a sheet name in case your macro ever does processing on different sheets. So it would be even better to change the code to:
cellAimsID = wsDest.Cells(a.Row, 1)
cellAimsID = wsDest.Cells(a.Row, 1)
This is my code after changes,
It allows the export of a worksheet in text file with specific template.
PS : Last line have a close Array so I did it outside the range.
Option Explicit
Sub txtFile()
Dim strPath As String
Dim fso As Object
Dim ts As Object
Dim wsDest As Worksheet
Set wsDest = Sheets("Filter FS")
wsDest.Select
Set fso = CreateObject("Scripting.FileSystemObject")
Dim cellAimsID As Variant
Dim cellAmount As Variant
Dim cellCurrencyISO As Variant
Dim cellReason As Variant
Dim cellExpiryDate As Variant
Dim FirstRow As String
Dim LastRow As String
Dim LastRowB As String
Dim a As Range, b As Range, cell As String, rng As Range, Lastrng As Range
Set a = Selection
Set ts = fso.CreateTextFile("C:\Users\cben\Documents\BKC\FinancialSecurity\test20.txt", True, True)
' for each cell in the worksheet create a line in text fil
FirstRow = wsDest.UsedRange.Rows(1).Row
LastRow = wsDest.Range("A" & Rows.Count).End(xlUp).Row
LastRowB = (wsDest.Range("A" & Rows.Count).End(xlUp).Row) - 1
Set rng = wsDest.Range("A2:A" & LastRowB)
Set Lastrng = wsDest.Range("A" & LastRow)
ts.WriteLine ("{")
ts.WriteLine (Chr(9) & "“cases”" & ": [")
For Each a In rng
cellAimsID = Cells(a.Row, 1)
cellCurrencyISO = Cells(a.Row, 2)
cellAmount = Cells(a.Row, 3)
cellReason = Cells(a.Row, 4)
cellExpiryDate = Cells(a.Row, 5)
'AimsID, Amount, Currency, Reason, ExpiryDate are the name of columns in worksheet
ts.WriteLine (Chr(9) & "{")
ts.WriteLine (Chr(9) & "“AimsID”" & ":" & Chr(9) & cellAimsID & ",")
ts.WriteLine (Chr(9) & "“Amount”" & ":" & Chr(9) & cellAmount & ",")
ts.WriteLine (Chr(9) & "“CurrencyISO”" & ":" & Chr(9) & cellCurrencyISO & ",")
ts.WriteLine (Chr(9) & "“Reason”" & ":" & Chr(9) & cellReason & ",")
ts.WriteLine (Chr(9) & "“ExpiryDate”" & ":" & Chr(9) & "“" & cellExpiryDate & "”")
ts.WriteLine (Chr(9) & "}" & ",")
Next
cellAimsID = Cells(LastRow, 1)
cellCurrencyISO = Cells(LastRow, 2)
cellAmount = Cells(LastRow, 3)
cellReason = Cells(LastRow, 4)
cellExpiryDate = Cells(LastRow, 5)
ts.WriteLine (Chr(9) & "{")
ts.WriteLine (Chr(9) & "“AimsID”" & ":" & Chr(9) & cellAimsID & ",")
ts.WriteLine (Chr(9) & "“Amount”" & ":" & Chr(9) & cellAmount & ",")
ts.WriteLine (Chr(9) & "“CurrencyISO”" & ":" & Chr(9) & cellCurrencyISO & ",")
ts.WriteLine (Chr(9) & "“Reason”" & ":" & Chr(9) & cellReason & ",")
ts.WriteLine (Chr(9) & "“ExpiryDate”" & ":" & Chr(9) & "“" & cellExpiryDate & "”")
ts.WriteLine (Chr(9) & "}" & "]")
ts.WriteLine ("}")
ts.Close
End Sub

Excel VBA: Macro to only export non blank cells

Good day everyone,
I have this macro, which exports all cells with formulas, BUT with blank outputs.
I only want the cells displaying as non blank to export. Any ideas?
Sub Export_A()
Dim sPath As String
Dim SFile As String
Dim nLog As Integer
sPath = "C:\AAAWork\"
SFile = sPath & ActiveSheet.Range("P9") & ".txt"
nfile = FreeFile
Open SFile For Output As #nfile
For i = 1 To ActiveSheet.UsedRange.Rows.Count
Set ThisCell = ActiveSheet.Range("A" & i)
If ThisCell.Text <> "" Then
' sInDate = ThisCell.Text
'sOutDate = Format(ThisCell.Value, "mm/yyyy")
sOutDate = Format(ThisCell.Value, "yyyy-mm")
'stemp = """" & sOutDate & """" this gives the date the " in the
beginning and end
stemp = "" & sOutDate & ""
For j = 1 To 10
If j = 1 Or j = 2 Or j = 9 Then
stemp = stemp & ";" & ThisCell.Offset(0, j)
Else
'stemp = stemp & "," & """" & ThisCell.Offset(0, j) & """" This
gives every value a " beginning and end
stemp = stemp & ";" & ThisCell.Offset(0, j)
End If
Next
End If
Print #nfile, stemp
Next
Close #nfile
MsgBox ("Completed a file called " & SFile & " has been generated")
End Sub
This is an interesting way of exporting to CSV, but it was inherited and does everything else very well.
Try placing the Write line at the end of the For loop
Sub Export_A()
Dim sPath As String
Dim SFile As String
Dim nLog As Integer
sPath = "C:\AAAWork\"
SFile = sPath & ActiveSheet.Range("P9") & ".txt"
nfile = FreeFile
Open SFile For Output As #nfile
For i = 1 To ActiveSheet.UsedRange.Rows.Count
Set ThisCell = ActiveSheet.Range("A" & i)
If ThisCell.Text <> "" Then
' sInDate = ThisCell.Text
'sOutDate = Format(ThisCell.Value, "mm/yyyy")
sOutDate = Format(ThisCell.Value, "yyyy-mm")
'stemp = """" & sOutDate & """" this gives the date the " in the beginning and end
stemp = "" & sOutDate & ""
For j = 1 To 10
stemp = stemp & ";" & ThisCell.Offset(0, j)
Next
Print #nfile, stemp
End If
Next
Close #nfile
MsgBox ("Completed a file called " & SFile & " has been generated")
End Sub
first you don't need this if statement as the output is the same if it's true or false
If j = 1 Or j = 2 Or j = 9 Then
stemp = stemp & ";" & ThisCell.Offset(0, j)
Else
'stemp = stemp & "," & """" & ThisCell.Offset(0, j) & """" This gives every value a " beginning and end
stemp = stemp & ";" & ThisCell.Offset(0, j)
End If
If the blanks are in the following columns you could change to code to:
If ThisCell.Offset(0, j) <> "" Then
stemp = stemp & ";" & ThisCell.Offset(0, j)
End If
Which will skip blank columns

Resources