Interop - save UTF-8 .csv to .xlsx - vb.net

Using Excel.Interop I want to open a .txt or .csv file and save it as an excel file. Most of the times this simple code works:
Dim Exl As New Excel.Application()
Dim wb1 As Excel.Workbook = Exl.Workbooks.Open("C:\MyFile.txt", Format:=4)
wb1.SaveAs("C:\MyFile.xlsx", FileFormat:=Excel.XlFileFormat.xlOpenXMLWorkbook)
wb1.Close()
Exl.Quit()
However sometimes the .txt/.csv that is being converted contains special characters like ü, ä or ö - and in these cases these characters are replaced by other characters in the resulting excel file.
The problem seems to be that the input files are UTF-8 encoded. So I tried to change the second line to
Dim wb1 As Excel.Workbook = Exl.Workbooks.Open("C:\MyFile.txt", Format:=4, Origin:=61005)
which doesn't work either.
Another option that I came across was to simply use OpenText instead of Open, however now I get an exception:
Dim wb1 As Excel.Workbooks
wb1.OpenText("C:\MyFile.txt")
Exl.wb1.SaveAs("C:\MyFile.xlsx", FileFormat:=Excel.XlFileFormat.xlOpenXMLWorkbook)
wb1.Close()
Exl.Quit()
Thank you for any help!

The Origin parameter of the Workbooks.Open Method must be a value from the XlPlatform enumeration;
Name Value Description
xlMacintosh 1 Macintosh
xlMSDOS 3 MS-DOS
xlWindows 2 Microsoft Windows
Your code:
wb1 As Excel.Workbook = Exl.Workbooks.Open("C:\MyFile.txt", Format:=4, Origin:=61005)
is trying to specify a code page identifier. This is supported by the Origin parameter of the Workbooks.OpenText Method. Additionally, you have a transcription error in the identifier value; it should be 65001 not 61005.
Here is an example using then OpenText method.
Sub Example()
Const UTF8CodePage As Int32 = 65001
Dim app As New Excel.Application
app.Visible = True
Dim filePath As String = "F:\TestUTF_8Quoted.txt"
Dim fi As New IO.FileInfo(filePath)
app.Workbooks.OpenText(Filename:=filePath, Semicolon:=True, Origin:=UTF8CodePage, TextQualifier:=Excel.XlTextQualifier.xlTextQualifierDoubleQuote)
Dim wb As Excel.Workbook = app.Workbooks.Item(fi.Name)
wb.Close(False)
app.Quit()
End Sub

Related

Is there any way to specify the encoding UTF-8 in SpreadsheetGear to generate CSV files?

Below is my sample VB.Net code to generate CSV file but I don't find a way to specify UTF-8 encoding. Can anyone help me on this?
Public Sub GenerateCsvFile(ByVal dt As DataTable, ByVal strFilePath As String)
Dim workbook As SpreadsheetGear.IWorkbook
Dim worksheet As SpreadsheetGear.IWorksheet
workbook = SpreadsheetGear.Factory.GetWorkbook()
worksheet = workbook.Worksheets("Sheet1")
Dim cells As SpreadsheetGear.IRange
cells = worksheet.Cells("A1")
cells.CopyFromDataTable(dt, Data.SetDataFlags.AllText)
workbook.SaveAs(strFilePath, SpreadsheetGear.FileFormat.CSV)
worksheet = Nothing
workbook.Close()
workbook = Nothing
End Sub
Note: The below link which is similar question asked in 2015 and I was wondering with the latest dll has the solution for this

Can GetObject do this?

I'm currently working on developing a macro that will input various forms into an access database.
Due to the nature of the beast of this program, I've had to split my main program into two sub programs and call them, but I need to use getobject to call a file path twice now.
I use getobject to open a file, and then use myrec.fields(~column name~) = xlsht.cells(1, "a") to populate various column values. I'm unsure if there are other "efficient" ways to accomplish this.
I was wondering if it is possible to use a variable in place of the filepath with the GetObject command, instead of needing to manually replace the file path in the code.
I've tested a fair amount of different code, including the path, class functionality but I don't think I understand VBA enough to truly make the best use of that.
I can make it work using this
Dim XL As Variant
Dim XLApp As Variant
Dim XLsht As Variant
Dim XLwrkbk As Variant
Set XL = CreateObject("Excel.Application")
Set XLwrkbk = GetObject(~file path~)
Set XLsht = XLwrkbk.Worksheets(1)
Set MyRec = CurrentDb.OpenRecordset("database name")
Ideally I would like it to be
Dim filename As String
Dim XL As Variant
Dim XLApp As Variant
Dim XLsht As Variant
Dim XLwrkbk As Variant
filename = " ~insert file path~ "
Set XL = CreateObject("Excel.Application")
Set XLwrkbk = GetObject(filename)
Set XLsht = XLwrkbk.Worksheets(1)
Set MyRec = CurrentDb.OpenRecordset("database name")
I receive a run time error
Run-time error '5':
Invalid procedure call or argument.
Try something like this:
Dim XL As New Excel.Application, Filename As String
Filename = "~ your file ~"
XL.Workbooks.Open (Filename)
myrec.fields(~column name~) = XL.Worksheets(1).Range("A1").value

Insert pictures to hidden Excel file

I am trying to insert text and pictures from a specific folder to a hidden Excel file, in specific cells, but for some reason I do not succeed in adding the pictures to the file.
What I can is open a hidden Excel file and add a bunch of data to the Excel. I can also add pictures tot the Excel from which the VBA script is running.
However combining both is something where I fail.
I use the following code to open an Excel file and put data in there:
Dim ExcelFileName As String
ExcelFileName = "C:\PictureTest.xlsx"
Dim Workbook As New Excel.Application
Dim DataWorkbook As New Excel.Workbook
Set DataWorkbook = Workbook.Workbooks.Open(ExcelFileName)
Workbook.Sheets("Sheet1").Cells(1, 1) = "Data to CELL"
DataWorkbook.Save
DataWorkbook.Close
Set Workbook = Nothing
Set DataWorkbook = Nothing
This one works perfectly, I can put data in any sheet anywhere I want.
However I also need to put pictures on certain sheets/cells.
I use the following code to add a picture to the active Excel file from which I am running the VBA script:
Dim PicturePath As String
PicturePath = "C:\Picture.tif"
Dim strPath As String
Dim Picture As Object
Set Picture = ActiveSheet.Pictures.Insert(PicturePath)
Picture.ShapeRange.LockAspectRatio = msoCTrue
Picture.Placement = xlMoveAndSize
Picture.ShapeRange.Width = 0.3 * Picture.Width
Is there anyone who can help me in getting both combined?

Automation of PDF String Search using Excel VBA - OLE error

I'm getting this error, "Microsoft Excel is waiting for another application to complete an OLE action" when trying to automate a PDF string search and record findings in excel. For certain PDFs this error is not popping. I assume this is due to the less optimized PDFs taking a longer time to search string while indexing page by page.
To be more precise, I have a workbook containing two sheets. One contains a list of PDF file names and the other has a list of words that I want to search. From the file list the macro would open each PDF file and take each word from the list of words and perform a string search. If found it would record each finding in a new sheet in the same workbook with the file name and the found string.
Below is the code I'm struggling with. Any help is welcome.
Public Sub SearchWords()
'variables
Dim ps As Range
Dim fs As Range
Dim PList As Range
Dim FList As Range
Dim PLRow As Long
Dim FLRow As Long
Dim Tracker As Worksheet
Dim gapp As Object
Dim gAvDoc As Object
Dim gPDFPath As String
Dim sText As String 'String to search for
FLRow = ActiveWorkbook.Sheets("List Files").Range("B1").End(xlDown).Row
PLRow = ActiveWorkbook.Sheets("Prohibited Words").Range("A1").End(xlDown).Row
Set PList = ActiveWorkbook.Sheets("Prohibited Words").Range("A2:A" & PLRow)
Set FList = ActiveWorkbook.Sheets("List Files").Range("B2:B" & FLRow)
Set Tracker = ActiveWorkbook.Sheets("Tracker")
'For each PDF file list in Excel Range
For Each fs In FList
'Initialize Acrobat by creating App object
Set gapp = CreateObject("AcroExch.App")
'Set AVDoc object
Set gAvDoc = CreateObject("AcroExch.AVDoc")
'Set PDF file path to open in PDF
gPDFPath = fs.Cells.Value
' open the PDF
If gAvDoc.Open(gPDFPath, "") = True Then
'Bring the PDF to front
gAvDoc.BringToFront
'For each word list in the range
For Each ps In PList
'Assign String to search
sText = ps.Cells.Value
'This is where the error is appearing
If gAvDoc.FindText(sText, False, True, False) = True Then
'Record findings
Tracker.Range("A1").End(xlDown).Offset(1, 0) = fs.Cells.Offset(0, -1).Value
Tracker.Range("B1").End(xlDown).Offset(1, 0) = ps.Cells.Value
End If
Next
End If
'Message to display once the search is over for a particular PDF
MsgBox (fs.Cells.Offset(0, -1).Value & " assignment complete")
Next
gAvDoc.Close True
gapp.Exit
set gAVDoc = Nothing
set gapp = Nothing
End Sub
I have now found the answer to this problem.
I'm using Acrobat Pro and whenever I open a PDF file, it opens with limited features due to Protected View settings. If I disable this function or if I click Enable All Features and save changes to the PDF files, VBA macro runs smooth.
It's funny, I'm posting an answer to my own problem.

Opening and Excel file in Access using VBA and saving it to a different name and closing it properly

I have been searching for some time on how exactly to go about this, but I keep coming up with a large number of possible ways that come close, but never really give me exactly the sort of thing I'm looking for. The concept is pretty simple I need to open a certian .xls file using some VBA code in Access 2010. Once the file is opened I need to insert data and do some things to the file then save the file as a different filename and close the file. I also need it to close excel if it was not already open and if it was open I need it to leave excel alone and not save/close anything other than the template.xls file I am working with. I currently have code that will do part of this provided Excel is not already open at the time the script runs. When excel is already opened I get the following error;
"Run-time'91': Object variable or With block variable not set."
When I click debug I get the following line highlighted
x.ActiveWorkbook.SaveAs fileName:=savedfilename
Here is the code without all the junk that doesn't relate to the issue. I have cobbled together using examples from various sites.
Dim DateSampled As String
Dim strPath As String
Dim TemplatePath As String
Dim x As Excel.Application
Dim xBook As Excel.Workbook
Dim xSheet As Excel.Worksheet
DateAsString = Format(DateSampled, "MMDDYYYY")
savedfilename = strPath & "\" & TrainNum & "-" & DateAsString & ".xls"
TemplatePath = "B:\template.xls"
Set x = CreateObject("Excel.Application")
x.Visible = False
Set xBook = GetObject(TemplatePath)
xBook.Windows(1).Visible = True
Set xSheet = xBook.Worksheets(1)
'---------------CODE DOES STUFF WITH THE FILE -----------------------
x.DisplayAlerts = False
x.ActiveWorkbook.SaveAs fileName:=savedfilename
x.DisplayAlerts = True
x.ActiveWorkbook.Close
Set x = Nothing
Set xBook = Nothing
Set xSheet = Nothing