I am using this procedure to export a cell range to JSON.
Sub export_json(mysheet As Worksheet, myrange As String)
Dim fs As Object
Dim jsonfile
Dim rangetoexport As Range
Dim rowcounter As Long
Dim columncounter As Long
Dim linedata As String
Dim path As String
Dim fname As String
Set rangetoexport = mysheet.Range(myrange)
path = ThisWorkbook.path & "\"
fname = clean_filename(myrange, "") & ".json"
Set fs = CreateObject("Scripting.FileSystemObject")
Set jsonfile = fs.CreateTextFile(path & fname, True)
linedata = "{""Output"": ["
jsonfile.WriteLine linedata
For rowcounter = 2 To rangetoexport.Rows.Count
linedata = ""
For columncounter = 1 To rangetoexport.Columns.Count
linedata = linedata & """" & rangetoexport.Cells(1, columncounter) & """" & ":" & """" & rangetoexport.Cells(rowcounter, columncounter) & """" & ","
Next
linedata = Left(linedata, Len(linedata) - 1)
If rowcounter = rangetoexport.Rows.Count Then
linedata = "{" & linedata & "}"
Else
linedata = "{" & linedata & "},"
End If
jsonfile.WriteLine linedata
Next
linedata = "]}"
jsonfile.WriteLine linedata
jsonfile.Close
Set fs = Nothing
End Sub
However, if a cell value contains double quotes ", the output of JSON file becomes corrupt. Any ideas on how to fix this?
You need to escape the double quotes with a slash.
For columncounter = 1 To rangetoexport.Columns.Count
linedata = linedata & """" & Replace(rangetoexport.Cells(1, columncounter), """", "\""") & """" & ":" & """" _
& Replace(rangetoexport.Cells(rowcounter, columncounter), """", "\""") & """" & ","
Next
This answer give more details about escaping json. https://stackoverflow.com/a/19176131/7182460
Related
I have a string in this format similar to the json. Generated by the following code:
str = "{"
str &= Chr(34) & "code" & Chr(34) + ":" & Chr(34) & "0000001" & Chr(34)
str &= Chr(34) & "name" & Chr(34) + ":" & Chr(34) & "product 1" & Chr(34)
str &= Chr(34) & "value" & Chr(34) + ":" & Chr(34) & "150.00" & Chr(34)
str &= "}"
I just need to get the value after the code, name and value.
I cannot find an effective method to do this, as I will have to generalize to more terms later. How can I do this without transforming to JSON?
The code snippet you provide produces this string:
{"code":"0000001""name":"product 1""value":"150.00"}
Assuming you really are using VB6 to process this string, the following code breaks out the values:
Private Sub Test(ByVal str As String)
Dim groups As Variant
Dim values As Variant
Dim i As Integer
str = Replace(str, "{", "")
str = Replace(str, "}", "")
str = Replace(str, """""", ",")
str = Replace(str, """", "")
groups = Split(str, ",")
For i = LBound(groups) To UBound(groups)
values = Split(groups(i), ":")
Debug.Print values(1)
Next
End Sub
Something like this should help (untested):
colon% = 0
Dim completed as Boolean
while completed = false
colon% = InStr(colon% + 1, str, ":")
If colon% > 0 Then
value$ = Mid$(str, colon + 1, InStr(colon% + 2, str, Chr(34)) - colon%)
' ... do whatever with value$ here...
Else
completed = true
End If
Wend
I am trying to export a selected range to json and repeatedly run into the same problems receiving error messages "Sub or Function not defined".
Sub PrintJson()
Dim fs As Object
Dim jsonfile
Dim rangetoexport As Range
Dim rowcounter As Long
Dim columncounter As Long
Dim linedata As String
Dim path As String
Dim fname As String
Set rangetoexport = Sheets("Marketing").Range("C6", Range("C6").End(xlDown).End(xlToRight))
path = ThisWorkbook.path & "\"
fname = "export.json"
Set fs = CreateObject("Scripting.FileSystemObject")
Set jsonfile = fs.CreateTextFile(path & fname, True)
linedata = "{""Output"": ["
jsonfile.WriteLine linedata
For rowcounter = 2 To rangetoexport.Rows.Count
linedata = ""
For columncounter = 1 To rangetoexport.Columns.Count
linedata = linedata & """" & Replace(rangetoexport.Cells(1, columncounter), """", "\""") & """" & ":" & """" _
& Replace(rangetoexport.Cells(rowcounter, columncounter), """", "\""") & """" & ","
Next
linedata = Left(linedata, Len(linedata) - 1)
If rowcounter = rangetoexport.Rows.Count Then
linedata = "{" & linedata & "}"
Else
linedata = "{" & linedata & "},"
End If
jsonfile.WriteLine linedata
Next
linedata = "]}"
jsonfile.WriteLine linedata
jsonfile.Close
Set fs = Nothing
End Sub
I am really new to VBA and just learning. But this confuses me, so any help appreciated.
I am giving a spreedsheet and I need to convert into JSON.
I have the following spreadsheet as so:
In essence, I'd need to convert into like this:
{ "CompanyA": {
"Products": ["Beds", "Knifes", "Spoons"]
}, "CompanyB": {
"Products": ["Beds", "Knifes", "Spoons"],
"Sites": ["West Coast", "East Coast"]
}, "CompanyC": {
"Office": ["Los Angeles"]
}}
I tried looking at online sources, but I haven't got a good solution to what I am looking for
Here's some basic code which should point you to the right direction.
I have commented it as much as possible.
Sub GetJSONOutput()
Dim wks As Worksheet: Set wks = ActiveSheet
Dim lngLastRow As Long, i As Long, j As Long, k As Long
Dim blFirstRow As Boolean
Dim strOut As String
lngLastRow = wks.Cells.Find("*", wks.Cells(1, 1), , , , xlPrevious).Row
k = 1
For i = 1 To lngLastRow
'\\ First Element - Column A
'\\ Check for first line and build beginning style
If Len(wks.Cells(i, 1).Value) > 0 Then
If blFirstRow = False Then
strOut = "{ """ & wks.Cells(i, 1).Value & """: {"
blFirstRow = True
Else '\\ Rest follow the same style
strOut = "}, """ & wks.Cells(i, 1).Value & """: {"
End If
wks.Cells(k, 4).Value = strOut: k = k + 1 '--> Output Column D
End If
'\\ Middle element - Column B
If Len(wks.Cells(i, 2).Value) > 0 Then strbase = " """ & wks.Cells(i, 2).Value & """: ["
If Len(wks.Cells(i, 3).Value) > 0 Then
'\\ Now we have Middle element then we need to loop through all elements under it!
'\\ Last Element - Column C
If Len(wks.Cells(i + 1, 3).Value) > 0 Then
strAppend = ""
For j = i To wks.Cells(i, 3).End(xlDown).Row
strAppend = strAppend & "|" & wks.Cells(j, 3).Value
Next j
strOut = strbase & """" & Replace(Mid(strAppend, 2, Len(strAppend)), "|", Chr(34) & ", " & Chr(34)) & """]"
wks.Cells(k, 4).Value = strOut: k = k + 1 '--> Output Column D
i = j - 1
Else
strOut = strbase & """" & wks.Cells(i, 3).Value & """]"
wks.Cells(k, 4).Value = strOut: k = k + 1 '--> Output Column D
End If
End If
'\\ Complete output by outputting the last closing brackets
If i = lngLastRow Then
strOut = "}}"
wks.Cells(k, 4).Value = strOut '--> Output Column D
End If
Next i
End Sub
Sub ConvertToJSONText()
Dim Sht As Worksheet
Set Sht = Worksheets("Sheet1")
Dim a As Integer
Dim lstA
Dim lstB
Dim lstC
a = 0
Dim myJsonText
myJsonText = "{"
Do While True
a = a + 1
If Sht.Range("a" & a).Value = "" And Sht.Range("b" & a).Value = "" And Sht.Range("c" & a).Value = "" Then
Exit Do
End If
If Sht.Range("a" & a).Value <> "" And Sht.Range("b" & a).Value = "" And Sht.Range("c" & a).Value = "" Then
If lstB <> "" Then myJsonText = myJsonText & "]"
If lstA <> "" Then myJsonText = myJsonText & "},"
lstA = Sht.Range("a" & a).Value
lstB = ""
lstC = ""
myJsonText = myJsonText & """" & lstA & """: {"
End If
If Sht.Range("a" & a).Value = "" And Sht.Range("b" & a).Value <> "" And Sht.Range("c" & a).Value = "" Then
If lstB <> "" Then myJsonText = myJsonText & "]"
lstB = Sht.Range("B" & a).Value
lstC = ""
myJsonText = myJsonText & """" & lstB & """: ["
End If
If Sht.Range("a" & a).Value = "" And Sht.Range("b" & a).Value = "" And Sht.Range("c" & a).Value <> "" Then
If lstC <> "" Then myJsonText = myJsonText & ","
lstC = Sht.Range("C" & a).Value
myJsonText = myJsonText & """" & lstC & """"
End If
Loop
If lstB <> "" Then myJsonText = myJsonText & "]"
myJsonText = myJsonText & "}"
End Sub
I'm writing VBA code for an application in Access for the first time and have created two separate strings to filter a report. The first of these strFilter filters the reports based on criteria in a list box. The second strWhere has been set up to filter the report based on a date input into a pair of text boxes. Both of these string filters work perfectly when used separately.
What I want to know is if there is a way to combine the two strings easily so that the user an filter the report based on both the criteria in the list box and the date they have entered in the text boxes.
The code I have for the listbox filter when it is added to the reports filter currently looks like this:
With Reports![rptFaultRecords]
.Filter = strFilter
.FilterOn = True
I want to add the string to filter by date strWhere next to the strFilter so the report can be filtered by both date and list criteria. All the code I've entered when attempting to do this has given me a run time error 3075. Is it possible for these two strings to be combined easily and if so how can I do it?
The rest of the code I've written is below if you need to see it:
Private Sub btnAllFaultsFilter_Click()
Dim varItem As Variant
Dim strRoom As String
Dim strFilter As String
Dim strDevice As String
Dim strCat As String
Dim strStatus As String
Dim strDateField As String
Dim strWhere As String
Const strcJetDate = "\#mm\/dd\/yyyy\#"
strDateField = "[f_datereported]"
If IsDate(Me.txtStartDate) Then
strWhere = "(" & strDateField & " >= " & Format(Me.txtStartDate, strcJetDate) & ")"
End If
If IsDate(Me.txtEndDate) Then
If strWhere <> vbNullString Then
strWhere = strWhere & " AND "
End If
strWhere = strWhere & "(" & strDateField & " < " & Format(Me.txtEndDate + 1, strcJetDate) & ")"
End If
For Each varItem In Me.lstRoom.ItemsSelected
strRoom = strRoom & ",'" & Me.lstRoom.ItemData(varItem) & "'"
Next varItem
If Len(strRoom) = 0 Then
strRoom = "Like '*'"
Else
strRoom = Right(strRoom, Len(strRoom) - 1)
strRoom = "IN(" & strRoom & ")"
End If
For Each varItem In Me.lstDevice.ItemsSelected
strDevice = strDevice & ",'" & Me.lstDevice.ItemData(varItem) & "'"
Next varItem
If Len(strDevice) = 0 Then
strDevice = "Like '*'"
Else
strDevice = Right(strDevice, Len(strDevice) - 1)
strDevice = "IN(" & strDevice & ")"
End If
For Each varItem In Me.lstCategory.ItemsSelected
strCat = strCat & ",'" & Me.lstCategory.ItemData(varItem) & "'"
Next varItem
If Len(strCat) = 0 Then
strCat = "Like '*'"
Else
strCat = Right(strCat, Len(strCat) - 1)
strCat = "IN(" & strCat & ")"
End If
For Each varItem In Me.lstStatus.ItemsSelected
strStatus = strStatus & ",'" & Me.lstStatus.ItemData(varItem) & "'"
Next varItem
If Len(strStatus) = 0 Then
strStatus = "Like '*'"
Else
strStatus = Right(strStatus, Len(strStatus) - 1)
strStatus = "IN(" & strStatus & ")"
End If
strFilter = "[c_roomid] " & strRoom & " AND [f_computername] " & strDevice & " AND [f_faultcategory] " & strCat & " AND [f_faultstatus] " & strStatus
With Reports![rptFaultRecords]
'.Filter = strFilter
.Filter = strFilter
.FilterOn = True
End With
End Sub
I need your help. I woulod like to change one char by another but in all database and i have several table and fields. So i'm building a function in VB but that change nothing and i have no error. I think that my condition is false but i don't see how to correct it :/
Public Sub updateField()
Dim db As DAO.Database, td As DAO.TableDef, field As DAO.field
Dim rs As DAO.Recordset, sSQL As String, sData As String
Set db = CurrentDb
Change = "\"""
replaced = """"
'each table in db
For Each tbd In db.TableDefs
'each field in table
For Each fld In tbd.Fields
'check if String Data have my character
If InStr(1, fld.Name, Change) Then
sSQL = "UPDATE " & tbd.Name & " SET " & fld.Name & " = replace([" & fld.Name & "], " & Change & ", " & replaced & ")"
db.Execute sSQL
End If
Next
Next
End Sub
EDIT :
I finally find what's wrong. if some people are interested :
Set db = CurrentDb
Change = "\"""
replaced = """"
'each table in db
For Each tbd In db.TableDefs
'each field in table
For Each fld In tbd.Fields
If Left(tbd.Name, 4) <> "MSys" And Left(tbd.Name, 4) <> "~TMP" Then
If fld.Type = dbText Or fld.Type = dbMemo Then
sSQL = "UPDATE " & tbd.Name & " SET " & fld.Name & " = replace([" & fld.Name & "],'" & Chr(92) + Chr(34) & "','" & Chr(34) & "')"
db.Execute sSQL
'Debug.Print (sSQL)
End If
End If
Next
Next
Thx for your help guys ;)
If it should help there my solution :
Public Sub updateField()
Dim db As DAO.Database, td As DAO.TableDef, field As DAO.field
Dim rs As DAO.Recordset, sSQL As String, sData As String, change As String, replace As String
change = "\'"
replace = "'"
' simple quote = 39
' doulbe quote = 34
' antislash = 92
' retour chariot = 13
' n = 110
' r = 114
Set db = CurrentDb
'each table in db
For Each tbd In db.TableDefs
'each field in table
For Each fld In tbd.Fields
If Left(tbd.Name, 4) <> "MSys" And Left(tbd.Name, 4) <> "~TMP" Then
If fld.Type = dbText Or fld.Type = dbMemo Then
' \r\n
'sSQL = "UPDATE " & tbd.Name & " SET [" & fld.Name & "] = replace([" & fld.Name & "],'\r\n','" & Chr(13) & Chr(10) & "');"
' \"
'sSQL = "UPDATE " & tbd.Name & " SET [" & fld.Name & "] = replace([" & fld.Name & "],'" & Chr(92) + Chr(34) & "','" & Chr(34) & "');"
'db.Execute sSQL
sSQL = "UPDATE " & tbd.Name & " SET [" & fld.Name & "] = replace([" & fld.Name & "],'\''','''');"
db.Execute sSQL
'Debug.Print (sSQL)
End If
End If
Next
Next
End Sub
That's works for me ;)