How should I do JSON string to XML string conversion in VBA? - json

I am looking to convert a JSON string I retrieve from a local .json file in my VBA Macro, to an XML string so I could further map it into my sheet, using the commands at the end of my code below. Here's the VBA code I am using to get the json data stored in a local file -
Dim hf As Integer: hf = FreeFile
Dim data As String
Open "C:\Users\karti\Desktop\3CD-MRL v4 testing\test.json" For Input As #hf
data = Input$(LOF(hf), #hf)
Close #hf
Debug.Print data 'this works perfectly, data variable now has the json
'... in between here, I need to convert the above json string
' to an xml string so I can map it using below code
'after getting the xml, I'll store it in strXmlData variable and map it
Dim xxiImportXml As XlXmlImportResult
xxiImportXml = ActiveWorkbook.XmlMaps(1).ImportXml(XmlData:=strXmlData)
Now I need to create some code which takes in the json string (from the variable data) as parameter and converts it into an xml string and returns the converted xml string, so I can store it in strXmlData variable to map the xml to the schema in my sheet.
I found this vb.net code online which could help in converting json to xml - https://stackoverflow.com/a/33437996. But I don't know if this is useful for excel macros (which are in vba)... What should I do? Please guide me on this... Thanks! :)

Related

How to loop through full result set using foreach container in SSIS

I encounter an issue when trying to use SSIS to retrieve a full result set from excel file.
I got two variables
Here is the dashboard in control flow
#CriteriaResult returns the ADO Recordset
#CriteriaID is the variable I try to loop through under the object I just returned
I encounter the error:The type of the value being assigned to variable "User::CriteriaID" differs from the current variable type. Variables may not change type during execution. Variable types are strict, except for variables of type Object.
My data is a column: 1,2,3A,3B,3C...
Online reference told me to use script task to change the convert object(#CriteriaResult) so I can use the data inside of it.
My VBA code is:
Public Sub Main()
Dim dt As Data.DataTable
Dim ds As Data.DataSet = CType(Dts.Variables("User::CriteriaID").Value, DataSet)
dt = ds.Tables(0)
Dts.TaskResult = ScriptResults.Success
End Sub
May I know how should I revise my code to make it works?
You can try this approach to iterate with an ADO enumerator:
1. Import to recordset with Data Flow Task
2. Iterate in ForEach with ADO Enumarator to recordset object variable
3. Each iteration saves record value to a variable
This is the package screenshot

SSIS Scientific Notation Desirable

I am working on a SSIS project that scans a directory and loops through each excel files that will then be loaded into MSSQL. Currently, I am having an issue with 2966171 being represented as 2.966171e+006. Here is what I have:
1) The Excel Connection String is passing IMEX=1; (Import Export Mode)
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\\UNC\PATH\TO\Excel.xls;Extended Properties="EXCEL 8.0;HDR=NO;IMEX=1";
2) The has confirmed the data type for this field is DT_WSTR of length 255.
Things I have tried:
1) Changing the datatype in Excel to Text
2) Creating a script component that explicitly converts a string to a decimal back to a string. (Terrible Approach)
3) Casting in a derived column component.
EDIT: I must keep this column a DT_WSTR type, some other rows contain alphanumeric values.
use For-each loop controls to loop over excel files
and map the filepath into a variable (ex: #[User::strExcelFile])
in the foreach container you must use 2 dataflow tasks;
the first one contains an excel source and a script component as a destination, the second DataFlowTask is your task
if the excel files have the same structure you must follow the steps below:
open an excel file and change the entirecolumn type to number
in the excel connection manager choose this file
in the second dataflow task in the Excel Source set the delay validation property to true
in the first dataflow task int the script component
properties (script tab) put the variable "strExcelFile" in the read
only variables, And in the script you must do the following steps:
First Add Microsoft.Office.Interop.Excel.dll as a reference
Second read the ExcelFile path from the variable using the following code:
Imports Microsoft.Office.Interop.Excel
Dim strExcelFiles As String = String.Empty
Public Overrides Sub PreExecute()
MyBase.PreExecute()
strExcelFiles = Variables.strExcelFile
End Sub
Third, in The Main Sub write create an Excel.application set the Visible Property to false
Open the ExcelFile and Change the EntireColumnType to Number and save The Excel File and Close the application using the following Code:
Dim ColIdx As Integer = 0 'Number Column index
Dim appExcel As New Excel.Application
appExcel.Visible = False
Dim wrkbExcel As New Excel.Workbook
wrkbExcel = appExcel.Workbooks.Open(strExcelFile)
Dim wrkshExcel As Excel.Worksheet = wrkbExcel.Worksheets(0)
wrkshExcel.Cells(1, ColIdx).EntireColumn.NumberFormat = "0"
'this will change the EntireColumn Type to Number and eliminate scientific character E+
wrkbExcel.Close(True)
appExcel.Quit()
Brief, every Excel file must be edited before importing data from it because the scientific sign appear when a number is stored in a cell having a datatype different from number

DirectCast MySQL BLOB to a PictureBox

frmSingleRecord.picImage.Image = DirectCast(sdr("photo_index"), Image)
This code is from my MysqlDataReader and the photo_index is the Blob from my database. I got error from this code.
Unable to cast object of type 'System.Byte[]' to type
'System.Drawing.Image'.
If its possible to DirectCast a Blob to PictureBox how can I do this right? If not any suggestion will be great!
As noted, you cant cast a byte array to a PictureBox which is a UI control, but you can cast the binary BLOB to Byte() so you can create an image from it. Assuming you did save an Image as Byte() to the DB:
...
If rdr.Read() Then
buff = TryCast(rdr.Item(1), Byte())
If buff IsNot Nothing Then
Using ms As New MemoryStream(buff)
pBox.Image = Image.FromStream(ms)
End Using
End If
End If
First, TryCast tries to cast the field data to Byte() to avoid an Exception which could happen if only some rows have image data for them. If the cast worked, an image is created from the Byte() using a MemoryStream and assigned to the PictureBox.Image property. This is probably the reverse of how you got the data into the DB.
Note that you have created a new Image, so it is up to you to also dispose of it when you are done with it.

convert complex JSON to dataset using JSON schema

I have some complex JSON data (1-many relationships) and both a text file and URL reference to the schema. I need to convert the data to a System.Data.Dataset, perserving the data types and relationships in the schema.
At present, I've been able to create a dataset by converting the data to an XML document, but it does not read the schema and therefore the data columns are all text and the data relationship is not preserved.
Imports System.Data
Imports Newtonsoft.Json
Imports System.IO
Dim xml As XmlDocument = JsonConvert.DeserializeXmlNode(System.IO.File.ReadAllText("C:\jsondata.txt"), "rootnode")
Dim ds As New DataSet("Json Data")
Dim xr As XmlReader = New XmlNodeReader(xml)
ds.ReadXml(xr)
My programming language is VB.NET.
At this point I can see all the data in the appropriate tables, but the relationships are assigned by the converter and all the data is text. I don't see a way of referencing the schema in this or any other Json.net method.
Any help would be appreciated.

Access - Export images from Image controls in forms

I have been searching for a way to extract images from access forms. A search on Google will nearly always point to OLEtoDisk. This software allows to export images stored in OLE fields inside access tables. This is not what I want.
I have a form with some logos, headers and background images. Those images are making the database become bigger and bigger (because they are embedded in the form). I would extract them, place them on our server together with the back-end file and add them back to my forms but this time as linked images instead of embedded images.
I hope I am making myself clear. Any suggestions are welcome.
EDIT : Added the code I'm using to export an Image control's PictureData as an image file. This code doesn't work as intended. I found out that PictureData is a byte array but after copying it in a file, I get one NUL character every two characters.
Public Function savePict(pImage As Access.Image)
Dim fname As String 'The name of the file to save the picture to
Dim iFileNum As Double
fname = Environ("Temp") + "\temp.png" ' Destination file path
iFileNum = FreeFile 'The next free file from the file system
Open fname For Binary Access Write As iFileNum
Dim tbyte As Variant
Dim i As Double
'Write the byte array to the file
For i = 0 To Len(pImage.PictureData)
Put #iFileNum, , pImage.PictureData(i)
Next i
Close #iFileNum
End Function
The picture data is an EMF file, with a wrapper of 8 bytes.
This is your routine modified to use the correct file extension
Public Function savePict(pImage As Access.Image)
Dim fname As String 'The name of the file to save the picture to
Dim iFileNum As Double
Dim bArray() As Byte, cArray() As Byte
Dim lngRet As Long
fname = Environ("Temp") + "\temp.emf" ' Destination file path
iFileNum = FreeFile 'The next free file from the file system
' Resize to hold entire PictureData prop
ReDim bArray(LenB(pImage.PictureData) - 1)
' Resize to hold the EMF wrapped in the PictureData prop
ReDim cArray(LenB(pImage.PictureData) - (1 + 8))
' Copy to our array
bArray = pImage.PictureData
For lngRet = 8 To UBound(cArray)
cArray(lngRet - 8) = bArray(lngRet)
Next
Open fname For Binary Access Write As iFileNum
'Write the byte array to the file
Put #iFileNum, , cArray
Close #iFileNum
End Function
Finally here is the code that worked as intended : Export a PNG image from a form's Image control.
Public Function savePict(pImage As Access.Image)
Dim fname As String 'The name of the file to save the picture to
fname = Environ("Temp") + "\temp.png" ' Destination file path
Dim iFileNum As Double
iFileNum = FreeFile 'The next free file from the file system
Dim pngImage As String 'Stores the image data as a string
pngImage = StrConv(pImage.PictureData, vbUnicode) 'Convert the byte array to a string
'Writes the string to the file
Open fname For Binary Access Write As iFileNum
Put #iFileNum, , pngImage
Close #iFileNum
End Function
Take your form that has a background image or AutoFormat that you like
Right-click on the form in the Navigation Pane and select Export >> XML
On the first page of the wizard, select a destination to drop some files (Desktop is fine)
A small dialog will then appear with three check boxes
Select the first option (Data) and third option (Presentation) and then click OK
Click the Close button on the last page of the wizard after the export is complete
If you are looking to re-use the image in another access database (ie you lost the original image file, but want to use it elsewhere), a far easier method would be to import the object (form, report etc) into your new Access database using the External Data -> Access menu.
You can then just copy paste the image control where you want to use it...
Unfortunately copy/paste of image controls between Access databases doesnt work as you'd like.