I have 6 text files in one folder.
I want combine selected files in to one text using access.
I have tried this code without success, because the one text file is created but is empty
Can any one help me on this?
Thanks in advance, my code below.
Lines in the text file:
xN;xDate;xNode;xCO;
100;2017-09-26 00:00:00;Valley;D6;
101;2017-09-25 00:00:00;Valley;D3;
...
...
Code:
Dim xPath
Function xExtract()
Dim xArray() As Variant
Dim I As Integer
Dim StrFileName As String
xPath = CurrentProject.Path
PDS:
xArray = Array("D1", "D2", "D3", "D4", "D5", "D6")
new_file = "" & xPath & "\PDS.txt"
fn = FreeFile
Open new_file For Output As fn
Close
For I = 0 To UBound(xArray)
StrFileName = "\\myserver\inetpub\ftproot\PDS_" & xArray(I) & ".txt"
fn = FreeFile
Open StrFileName For Input As fn
Open new_file For Append As fn + 1
Line Input #fn, dato
Do While Not EOF(fn)
Line Input #fn, dato
dati = Split(dato, Chr(9))
For d = 0 To UBound(dati)
If d = 0 Then
dato = Trim(dati(d))
Else
dato = dato & ";" & Trim(dati(d))
End If
Next
Print #fn + 1, dato
Loop
Close
Next I
Application.Quit
End Function
Here's code that works for concatenating comma delimited text files (probably would work for any text files). Pretty crude. Needs error handler and would benefit from common dialog to select output folder and file name. Also I don't like using non-typed variables, but I don't know what type of object some of them are and can't figure it out from Microsoft help. Warning, don't put output in same folder - might result in endless loop - trust me I tried it
Public Function CFiles(Filepath As String) As String
Dim FSO As Scripting.FileSystemObject
Dim SourceFolder As Folder
Dim Filein As Object
Dim fileout As Object
Dim strText As String
Dim TheInputfile As Object
Dim filename As String
Set FSO = New Scripting.FileSystemObject
Set SourceFolder = FSO.GetFolder(Filepath)
Set fileout = FSO.CreateTextFile("c:\InvestmentsPersonal\files\backup\output.txt", ForAppending, False)
For Each Filein In SourceFolder.Files
filename = Filein.Name
Set TheInputfile = FSO.OpenTextFile(Filepath & filename, ForReading)
strText = TheInputfile.ReadAll
TheInputfile.Close
fileout.WriteLine strText
Next
fileout.Close
Set fileout = Nothing
Set Filein = Nothing
Set SourceFolder = Nothing
Set FSO = Nothing
CFiles = "c:\InvestmentsPersonal\files\backup\output.txt"
End Function
As your code works for files with windows EOL format (CR (Carriage Return) + LF (Line Feed)), I guess your files are UNIX EOL format (just LF, no CR), check this with a texteditor like e.g. Notepad++ (View->Show Symbol->Show End of Line). This causesLine Inputto read the whole file in one line as it breaks on CR. Then you skip the first line and nothing is inserted, because all text is in this line.
You can useFileSystemObjectto avoid this as it breaks on LF.
Function xExtract()
Const ForReading = 1, ForWriting = 2, ForAppending = 8 'iomode constants
Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0 'format constants
Dim xArray As Variant, dati As Variant
Dim i As Long, d As Long
Dim xPath As String, new_file As String, dato As String, StrFileName As String
Dim FSO As Object, TextStreamIn As Object, TextStreamOut As Object
xPath = CurrentProject.Path
new_file = xPath & "\PDS.txt"
xArray = Array("D1", "D2", "D3", "D4", "D5", "D6")
Set FSO = CreateObject("Scripting.FileSystemObject")
Set TextStreamOut = FSO.OpenTextFile(new_file, ForWriting, True, TristateUseDefault) 'open textstream to write
For i = 0 To UBound(xArray) 'loop through files
StrFileName = "\\myserver\inetpub\ftproot\PDS_" & xArray(i) & ".txt"
Set TextStreamIn = FSO.OpenTextFile(StrFileName, ForReading) ' open textstream to read
TextStreamIn.SkipLine 'skip first line with headers
Do Until TextStreamIn.AtEndOfStream 'loop through lines
dati = Split(TextStreamIn.Readline, Chr(9))
For d = 0 To UBound(dati)
If d = 0 Then
dato = Trim(dati(d))
Else
dato = dato & ";" & Trim(dati(d))
End If
Next
TextStreamOut.WriteLine dato 'write line to file
Loop
TextStreamIn.Close 'close textstream
Next i 'next file
TextStreamOut.Close
Set TextStreamOut = Nothing
Set TextStreamIn = Nothing
Set FSO = Nothing
Application.Quit
End Function
If you want to stay withOpen fileyou can split the first (and only) line on LF (Split(dato,vbLf) and ignore the first element, but you have to check the file is UNIX EOL format, FSO covers both.
Related
I have JSON file and this is a preview of its structure
Is there a way to cut off the 'allTests' part and export it to new JSON file?
Try the following. Special characters are preserved. Hopefully the relevant JSON is cut out.
Option Explicit
Public Sub GetJSONExtract()
Dim fso As Object, jsonFile As Object, jsonText As String, arr() As String
Set fso = CreateObject("Scripting.FileSystemObject")
Set jsonFile = fso.OpenTextFile("C:\Users\User\Desktop\Sample.json")
jsonText = jsonFile.ReadAll
arr = Split(jsonText, Chr$(34) & "allTests" & Chr$(34))
jsonText = Replace$(arr(2), ":", vbNullString, 1, 1)
jsonText = Split(jsonText, Chr$(34) & "time" & Chr$(34))(0)
jsonText = Left$(jsonText, InStrRev(jsonText, ",") - 1)
With fso.CreateTextFile("C:\Users\User\Desktop\Test.json")
.write jsonText
End With
End Sub
Using: https://github.com/VBA-tools/VBA-JSON
Sub ParseItOut()
Const f_PATH As String = "C:\Users\Tim\Desktop\"
Dim fso, j, obj, subObj
Set fso = CreateObject("scripting.filesystemobject")
j = fso.OpenTextFile(f_PATH & "sample.json").ReadAll()
Set obj = JsonConverter.ParseJson(j)
'get the required section
Set subObj = obj("results")(1)("allTests")
'write to file as JSON
fso.CreateTextFile(f_PATH & "sample_mod.json").Write JsonConverter.ConvertToJson(subObj)
End Sub
EDIT: this seems to be a problem -
Under allTests each item is an object with a single property/key (which is very large and contains embedded quotes escaped by \) and a value of true
The library I used seems to have an issue with that (or I don't know how to use it correctly...)
I have the following JSON response:
{
"status": "Success",
"label": "pdf_base64_string",
"order": "ABC123456"
}
I'm trying to save a PDF file from the Base64 string per the following code:
FileData = Base64DecodeString(pdf_base64_string)
fileNum = FreeFile
FilePath = "C:\label.pdf"
Open FilePath For Binary Access Write As #fileNum
Put #fileNum, 1, FileData
Close #fileNum
This results in a broken/invalid PDF file (not recognized by the PDF viewer).
Adapted from: Inserting an Image into a sheet using Base64 in VBA?
This works for me - saves the file to the same location as the workbook running the code.
Sub TestDecodeToFile()
Dim strTempPath As String
Dim b64test As String
'little face logo
b64test = "R0lGODlhDwAPAKECAAAAzMzM/////wAAACwAAAAADwAPAAACIISPeQHsrZ5ModrLlN48" & _
"CXF8m2iQ3YmmKqVlRtW4MLwWACH+H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw=="
strTempPath = ThisWorkbook.Path & "\temp.png" 'use workbook path as temp path
'save byte array to temp file
Open strTempPath For Binary As #1
Put #1, 1, DecodeBase64(b64test)
Close #1
End Sub
Private Function DecodeBase64(ByVal strData As String) As Byte()
Dim objXML As Object 'MSXML2.DOMDocument
Dim objNode As Object 'MSXML2.IXMLDOMElement
'get dom document
Set objXML = CreateObject("MSXML2.DOMDocument")
'create node with type of base 64 and decode
Set objNode = objXML.createElement("b64")
objNode.DataType = "bin.base64"
objNode.Text = strData
DecodeBase64 = objNode.nodeTypedValue
'clean up
Set objNode = Nothing
Set objXML = Nothing
End Function
Points need to take care of for pdf to base64
If you are converting the pdf to base64/blob for rest API then do not use string variables because the size of a string variable is 32200 only.
If you are using pdf for rest API then you need to read the pdf in binary-only [ do not read it by text]
In VBA JSON file is sent through the text-only so try to use the streams instead of the JSON file.
I am sharing the code which does the binary conversion of base64 of the pdf file.
Function EncodeFileBase64(FileName As String) As String
fileNum = FreeFile
Open FileName For Binary As fileNum
ReDim arrData(LOF(fileNum) - 1)
Get fileNum, , arrData
Close fileNum
Set objXML = New MSXML2.DOMDocument
Set objNode = objXML.createElement("b64")
objNode.DataType = "bin.base64"
objNode.nodeTypedValue = arrData
EncodeFileBase64 = objNode.text
EncodeFileBase64 = Replace(objNode.text, vbLf, "")
Set objNode = Nothing
Set objXML = Nothing
End Function
I've searched extensively on this subject and haven't been able to find just what I've been looking for... so here I go!
Basically, I have 2 HTML Files. 1, I export from excel to HTML each day. The 2nd file, has addition code/CSS for table headers and formats as well as a scroll bar and search function. What I do, is copy the necessary bits out of the exported file into the 2nd file so it updates with the latest data. The 2nd file then links in to a larger web page on the company intranet for staff to see their results.
I have an entire automated system in place, and how I have been currently accomplishing this is to use VBA to open Notepad++ (used as my HTML editor) and then manually make these changes. I have recorded a macro within Notepad++ to do the changes automatically using "CTRL F1" as the command, but VBA doesn't work well with the Sendkeys function when I use the shell command to open Notepad++ so it hasn't been a viable solution for automation.
I then researched some more and came across the below code which I have amended to suit my needs, to bypass Notepad++ altogether and turn the HTML into a string. Problem is, it isn't just 1 word I am needing to find and replace, it's 2 entire and separate sections of code. I thought I could use wildcards but it doesn't seem to want to work. Any help that will allow me to replace an entire block of HTML code with another, using excel VBA would be an absolute lifesaver. Thanks in advance!
PS: The below code works as written because I remove the wildcard so it's just finding a couple of words on 1 line and replacing it with the entire code from the source file. I need to be able to replace and entire section, with a specified section from the source file as well
Sub Find_Replace2()
Dim sTempSource As String, sTempDest As String
'Dim sTemp As String
Dim sBuf As String
Dim iFileNum As Integer
Dim sFileName As String
'locations of html files, sourcefile goes into destfile
Dim htmlSourcefile As String: htmlSourcefile = "I:\The Hub\Pages\Statistics\Incentive\STB Incentive\STB League2.html"
Dim htmlDestfile As String: htmlDestfile = "I:\The Hub\Pages\Statistics\Incentive\STB League - Copy.html"
sFileName = htmlDestfile
'Opens the above files, and converts them to big long strings
iFileNum = FreeFile
Open htmlDestfile For Input As iFileNum
Do Until EOF(iFileNum)
Line Input #iFileNum, sBuf
sTempDest = sTempDest & sBuf & vbCrLf
Loop
Close iFileNum
iFileNum = FreeFile
Open htmlSourcefile For Input As iFileNum
Do Until EOF(iFileNum)
Line Input #iFileNum, sBuf
sTempSource = sTempSource & sBuf & vbCrLf
Loop
Close iFileNum
'find and replace on string
sTempDest = Replace(sTempDest, "<!--Start of VBA insert -->", "<!--Start of VBA insert -->" & sTempSource & "<!--End of VBA insert -->")
'saves string back off as original file
iFileNum = FreeFile
Open sFileName For Output As iFileNum
Print #iFileNum, sTempDest
Close iFileNum
End Sub
The replace function will not work as you have it. The following code gets dest file code before > "!--insert vba....>" here in one text string, then it gets everything after "!--end insert vba..." in another text string
And we get only the table from the source file. (given that the table end tag is
</table>.
I saved a table to html and that is how my Excel ended the table.)
So we add together Dest1 + source table + dest2 for the final page.
I have it saving the file to a tester.html file so it won't ruin your original file until you have had the chance to test it.
Sub Find_Replace2()
Dim sTempSource As String, sTempDest As String, sTempDest1 As String, sTempDest2 As String
Dim sSource1 As Long, sSource2 As Long, sTempSource2 As String
Dim point1 As Long, point2 As Long, point3 As Long, point4 As Long
Dim sBuf As String
Dim iFileNum As Integer
'locations of html files, sourcefile goes into destfile
Dim htmlSourcefile As String: htmlSourcefile = "I:\The Hub\Pages\Statistics\Incentive\STB Incentive\STB League2.html"
Dim htmlDestfile As String: htmlDestfile = "I:\The Hub\Pages\Statistics\Incentive\STB League - Copy.html"
'Opens the above files, and converts them to big long strings
iFileNum = FreeFile
Open htmlDestfile For Input As iFileNum
Do Until EOF(iFileNum)
Line Input #iFileNum, sBuf
sTempDest = sTempDest & sBuf & vbCrLf
Loop
Close iFileNum
iFileNum = FreeFile
Open htmlSourcefile For Input As iFileNum
Do Until EOF(iFileNum)
Line Input #iFileNum, sBuf
sTempSource = sTempSource & sBuf & vbCrLf
Loop
Close iFileNum
point3 = InStr(1, sTempSource, "<table") - 1
point4 = InStr(point3, sTempSource, "</table>") + 8
sTempSource2 = Mid(sTempSource, point3, point4 - point3)
point1 = InStr(1, sTempDest, "<!--Start of VBA insert -->") + 27
point2 = InStr(point1, sTempDest, "<!--End of VBA insert -->")
sTempDest1 = Mid(sTempDest, 1, point1)
sTempDest1 = sTempDest1 & sTempSource2
sTempDest2 = sTempDest1 & Mid(sTempDest, point2, Len(sTempDest) - point2)
'saves string back to a tester file
iFileNum = FreeFile
Open "I:\The Hub\Pages\Statistics\Incentive\tester.html" For Output As iFileNum
Print #iFileNum, sTempDest2
Close iFileNum
End Sub
Sub Find_Replace2()
Dim sTempSource As String, sTempDest As String, sTempDest1 As String, sTempDest2 As String, sTempDest3 As String
Dim sTempSource2 As String, sTempSource3 As String
Dim point1 As Long, point2 As Long, point3 As Long, point4 As Long, point5 As Long, point6 As Long, point7 As Long, point8 As Long
Dim sBuf As String
Dim iFileNum As Integer
'locations of html files, sourcefile goes into destfile
Dim htmlSourcefile As String: htmlSourcefile = "I:\The Hub\Pages\Statistics\Incentive\STB Incentive\STB League2.html"
Dim htmlDestfile As String: htmlDestfile = "I:\The Hub\Pages\Statistics\Incentive\STB League - Copy.html"
'Opens the above files, and converts them to big long strings
iFileNum = FreeFile
Open htmlDestfile For Input As iFileNum
Do Until EOF(iFileNum)
Line Input #iFileNum, sBuf
sTempDest = sTempDest & sBuf & vbCrLf
Loop
Close iFileNum
iFileNum = FreeFile
Open htmlSourcefile For Input As iFileNum
Do Until EOF(iFileNum)
Line Input #iFileNum, sBuf
sTempSource = sTempSource & sBuf & vbCrLf
Loop
Close iFileNum
point3 = InStr(1, sTempSource, "<!--table")
point4 = InStr(point3, sTempSource, "-->") + 3
sTempSource2 = Mid(sTempSource, point3, point4 - point3)
point7 = InStr(1, sTempSource, "</tr>")
point8 = InStr(point7, sTempSource, "<!--END OF OUTPUT FROM EXCEL PUBLISH AS WEB PAGE WIZARD-->") + 58
sTempSource3 = Mid(sTempSource, point7, point8 - point7)
point1 = InStr(1, sTempDest, "<!--Start of VBA insert -->") + 27
point2 = InStr(point1, sTempDest, "<!--End of VBA insert -->") - 1
point5 = InStr(1, sTempDest, "<!--Start of VBA insert2 -->") + 28
point6 = InStr(point5, sTempDest, "<!--End of VBA insert2 -->") - 1
sTempDest1 = Mid(sTempDest, 1, point1)
sTempDest1 = sTempDest1 & sTempSource2
sTempDest2 = sTempDest1 & Mid(sTempDest, point2, point5 - point2)
sTempDest2 = sTempDest2 & sTempSource3
sTempDest3 = sTempDest2 & Mid(sTempDest, point6, Len(sTempDest) - point6)
'saves string back to a tester file
iFileNum = FreeFile
Open "I:\The Hub\Pages\Statistics\Incentive\STB League - Copy.html" For Output As iFileNum
Print #iFileNum, sTempDest3
Close iFileNum
End Sub
I have been trying desperately for months to automate a process whereby a csv file is downloaded, maned and saved in a given location.
so far I only managed with excel vba to open the web page and click the bottom to download the csv file, but the code stop and required a manual intervention to to be completed, i would like it to be fully automated if possible.
see the code used (I am not the author):
Sub WebDataExtraction()
Dim URL As String
Dim IeApp As Object
Dim IeDoc As Object
Dim ieForm As Object
Dim ieObj As Object
Dim objColl As Collection
URL = "http://www.bmreports.com/bsp/BMRSSystemData.php?pT=DDAD&zT=N&dT=NRT"
Set IeApp = CreateObject("InternetExplorer.Application")
IeApp.Visible = True
IeApp.Navigate URL
Do Until IeApp.ReadyState = READYSTATE_COMPLETE
Loop
Set IeDoc = IeApp.Document
For Each ele In IeApp.Document.getElementsByTagName("span")
If ele.innerHTML = "CSV" Then
Application.Wait (Now + TimeValue("0:00:15"))
DoEvents
ele.Click
'At this point you need to Save the document manually
' or figure out for yourself how to automate this interaction.
Test_Save_As_Set_Filename
File_Download_Click_Save
End If
Next
IeApp.Quit
End Sub"
thanks in advance
Nunzio
I am posting a second answer, since, as I believe my first answer is adequate for many similar applications, it does not work in this instance.
Why the other methods fail:
The .Click method: This raises a new window which expects user input at run-time, it doesn't seem to be possible to use the WinAPI to control this window. Or, at least not any way that I can determine. The code execution stops on the .Click line until the user manually intervenes, there is no way to use a GoTo or a Wait or any other method to circumvent this behavior.
Using a WinAPI function to download the source file directly does not work, since the button's URL does not contain a file, but rather a js function that serves the file dynamically.
Here is my proposed workaround solution:
You can read the webpage's .body.InnerText, write that out to a plain text/csv file using FileSystemObject and then with a combination of Regular Expressions and string manipulation, parse the data into a properly delimited CSV file.
Sub WebDataExtraction()
Dim url As String
Dim fName As String
Dim lnText As String
Dim varLine() As Variant
Dim vLn As Variant
Dim newText As String
Dim leftText As String
Dim breakTime As Date
'## Requires reference to Microsoft VBScript Regular Expressions 5.5
Dim REMatches As MatchCollection
Dim m As Match
'## Requires reference to Microsoft Internet Controls
Dim IeApp As InternetExplorer
'## Requires reference to Microsoft HTML object library
Dim IeDoc As HTMLDocument
Dim ele As HTMLFormElement
'## Requires reference to Microsoft Scripting Runtime
Dim fso As FileSystemObject
Dim f As TextStream
Dim ln As Long: ln = 1
breakTime = DateAdd("s", 60, Now)
url = "http://www.bmreports.com/bsp/BMRSSystemData.php?pT=DDAD&zT=N&dT=NRT"
Set IeApp = CreateObject("InternetExplorer.Application")
With IeApp
.Visible = True
.Navigate url
Do Until .ReadyState = 4
Loop
Set IeDoc = .Document
End With
'Wait for the data to display on the page
Do
If Now >= breakTime Then
If MsgBox("The website is taking longer than usual, would you like to continue waiting?", vbYesNo) = vbNo Then
GoTo EarlyExit
Else:
breakTime = DateAdd("s", 60, Now)
End If
End If
Loop While Trim(IeDoc.body.innerText) = "XML CSV Please Wait Data Loading Sorting"
'## Create the text file
fName = ActiveWorkbook.Path & "\exported-csv.csv"
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.OpenTextFile(fName, 2, True, -1)
f.Write IeDoc.body.innerText
f.Close
Set f = Nothing
'## Read the text file
Set f = fso.OpenTextFile(fName, 1, False, -1)
Do
lnText = f.ReadLine
'## The data starts on the 4th line in the InnerText.
If ln >= 4 Then
'## Return a collection of matching date/timestamps to which we can parse
Set REMatches = SplitLine(lnText)
newText = lnText
For Each m In REMatches
newText = Replace(newText, m.Value, ("," & m.Value & ","), , -1, vbTextCompare)
Next
'## Get rid of consecutive delimiters:
Do
newText = Replace(newText, ",,", ",")
Loop While InStr(1, newText, ",,", vbBinaryCompare) <> 0
'## Then use some string manipulation to parse out the first 2 columns which are
' not a match to the RegExp we used above.
leftText = Left(newText, InStr(1, newText, ",", vbTextCompare) - 1)
leftText = Left(leftText, 10) & "," & Right(leftText, Len(leftText) - 10)
newText = Right(newText, Len(newText) - InStr(1, newText, ",", vbTextCompare))
newText = leftText & "," & newText
'## Store these lines in an array
ReDim Preserve varLine(ln - 4)
varLine(ln - 4) = newText
End If
ln = ln + 1
Loop While Not f.AtEndOfStream
f.Close
'## Re-open the file for writing the delimited lines:
Set f = fso.OpenTextFile(fName, 2, True, -1)
'## Iterate over the array and write the data in CSV:
For Each vLn In varLine
'Omit blank lines, if any.
If Len(vLn) <> 0 Then f.WriteLine vLn
Next
f.Close
EarlyExit:
Set fso = Nothing
Set f = Nothing
IeApp.Quit
Set IeApp = Nothing
End Sub
Function SplitLine(strLine As String) As MatchCollection
'returns a RegExp MatchCollection of Date/Timestamps found in each line
'## Requires reference to Microsoft VBScript Regular Expressions 5.5
Dim RE As RegExp
Dim matches As MatchCollection
Set RE = CreateObject("vbscript.regexp")
With RE
.MultiLine = False
.Global = True
.IgnoreCase = True
'## Use this RegEx pattern to parse the date & timestamps:
.Pattern = "(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])[ ]\d\d?:\d\d:\d\d"
End With
Set matches = RE.Execute(strLine)
Set SplitLine = matches
End Function
EDIT
I tested my original answer code using the URL:
http://www.bmreports.com/bsp/BMRSSystemData.php?pT=DDAD&zT=N&dT=NRT#saveasCSV
But this method does not seem to work, for this site. The ele.Click doesn't seem to initiate the download, it just opens the data tabular on the webpage. To download, you need to do the right-click/save-as. If you have gotten that far (as I suspect, based on the subroutines you are calling, but for which you did not provide the code), then you can probably use the Win API to get the HWND of the Save dialog and possibly automate that event. Santosh provides some information on that:
VBA - Go to website and download file from save prompt
Here is also a good resource that should help solve your problem:
http://social.msdn.microsoft.com/Forums/en-US/beb6fa0e-fbc8-49df-9f2e-30f85d941fad/download-file-from-ie-with-vba
Original Answer
If you are able to determine the URL of the CSV then you can use this subroutine to open a connection to the CSV data and import it directly to the workbook. You may need to automate a text-to-columns operation on the imported data, but that can easily be replicated with the macro recorder. I put an example of this in the Test() subroutine below.
You could easily modify this to add the QueryTables in a new workbook, and then automate the SaveAs method on that workbook to save the file as a CSV.
This example uses a known URL for Yahoo Finance, Ford Motor Company, and will add a QueryTables with the CSV data in cell A1 of the active worksheet. This can be modified pretty easily to put it in another sheet, another workbook, etc.
Sub Test()
Dim MyURL as String
MyURL = "http://ichart.finance.yahoo.com/table.csv?s=GM&a0&b=1&c2010&d=05&e=20&f=2013&g=d&ignore=.csv"
OpenURL MyURL
'Explode the CSV data:
Range("A:A").TextToColumns Destination:=Range("A1"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=False, _
Semicolon:=False, Comma:=True, Space:=False, Other:=False, FieldInfo _
:=Array(Array(1, 3), Array(2, 1), Array(3, 1), Array(4, 1), Array(5, 1), Array(6, 1), _
Array(7, 1)), TrailingMinusNumbers:=True
End Sub
Private Sub OpenURL(fullURL As String)
'This opens the CSV in querytables connection.
On Error GoTo ErrOpenURL
With ActiveSheet.QueryTables.Add(Connection:= _
"URL;" & fullURL, Destination:=Range("A1"))
.Name = fullURL
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = True
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.WebSelectionType = xlEntirePage
.WebFormatting = xlWebFormattingAll
.WebPreFormattedTextToColumns = True
.WebConsecutiveDelimitersAsOne = True
.WebSingleBlockTextImport = False
.WebDisableDateRecognition = False
.WebDisableRedirections = False
.Refresh BackgroundQuery:=False
End With
ExitOpenURL:
Exit Sub 'if all goes well, you can exit
'Error handling...
ErrOpenURL:
Err.Clear
bCancel = True
Resume ExitOpenURL
End Sub
I have a large amount of csv files that I need in .xls format. Is it possible to run a batch conversion with a macro or best done with another language?
I have used this code http://www.ozgrid.com/forum/showthread.php?t=71409&p=369573#post369573 to reference my directory but I'm not sure of the command to open each file and save them. Here's what I have:
Sub batchconvertcsvxls()
Dim wb As Workbook
Dim CSVCount As Integer
Dim myVar As String
myVar = FileList("C:\Documents and Settings\alistairw\My Documents\csvxlstest")
For i = LBound(myVar) To UBound(myVar)
With wb
Application.Workbooks.OpenText 'How do I reference the myvar string ?
wb.SaveAs '....
End With
Next
End Sub
Function FileList(fldr As String, Optional fltr As String = "*.*") As Variant
Dim sTemp As String, sHldr As String
If Right$(fldr, 1) <> "\" Then fldr = fldr & "\"
sTemp = Dir(fldr & fltr)
If sTemp = "" Then
FileList = Split("No files found", "|") 'ensures an array is returned
Exit Function
End If
Do
sHldr = Dir
If sHldr = "" Then Exit Do
sTemp = sTemp & "|" & sHldr
Loop
FileList = Split(sTemp, "|")
End Function
Edit: The files are .txt files formatted as csv
By combining the code given by Scott Holtzman and 'ExcelFreak', the conversion works quite well. The final code looks something like this:
Sub CSV_to_XLS()
Dim wb As Workbook
Dim strFile As String, strDir As String
strDir = "U:\path\"
strFile = Dir(strDir & "*.csv")
Do While strFile <> ""
Set wb = Workbooks.Open(Filename:=strDir & strFile, Local:=True)
wb.SaveAs Replace(wb.FullName, ".csv", ".xls"), 50 'UPDATE:
wb.Close True
Set wb = Nothing
strFile = Dir
Loop
End Sub
Opening the converted .xls file throws a warning everytime:
"The file you are trying to open, 'filename', is in a different format than specified by the file extension. Verify that the file is not corrupted and is from a trusted source before opening the file. Do you want to open the file now?"
Clicking Yes then opens the .xls file.
Is there a way to get rid of this warning message? Excel throws a warning everytime the .xls file is opened.
In a lot less lines of code, this should get you what you want. However, I will say this may not be the fastest way to get it done, because you are opening, saving, and closing the workbook every time. I will look for a faster way, but I forget the method off the top of my head.
Sub batchconvertcsvxls()
Dim wb As Workbook
Dim strFile As String, strDir As String
strDir = "C:\"
strFile = Dir(strDir & "*.csv")
Do While strFile <> ""
Set wb = Workbooks.Open(strDir & strFile)
With wb
.SaveAs Replace(wb.FullName, ".csv", ".xls"), 50 'UPDATE:
.Close True
End With
Set wb = Nothing
Loop
End Sub
** UPDATE **
you need the proper fileformat enumeration for a .xls file. I think its 50, but you can check here Excel File Type Enumeration, if it's not.
The Code of Scott Holtzman nearly did it for me. I had to make two changes to get it to work:
He forgot to add the line that makes our loop continue with the next file. The last line before the Loop should read
strFile = Dir
The Workbooks.Open method did not read my CSV files as expected (the whole line ended up to be text in the first cell). When I added the parameter Local:=True it worked:
Set wb = Workbooks.Open(Filename:=strDir & strFile, Local:=True)
This works properly at least on Excel 2013. Using FileFormat:=xlExcel8 parameter instead of the filetype tag 50 creates files that open without security nags.
Sub CSV_to_XLS()
Dim wb As Workbook
Dim strFile As String, strDir As String
strDir = "C:\temp\"
strFile = Dir(strDir & "*.csv")
Do While strFile <> ""
Set wb = Workbooks.Open(Filename:=strDir & strFile, Local:=True)
wb.SaveAs Replace(wb.FullName, ".csv", ".xls"), FileFormat:=xlExcel8
wb.Close True
Set wb = Nothing
strFile = Dir
Loop
End Sub
This was a good question and I have found in the internet several answers. Just making very small changes (I couldn't edit any of the codes already published) I could make things work a bit better:
Sub CSV_to_XLSX()
Dim wb As Workbook
Dim strFile As String, strDir As String
strDir = "C:\Users\acer\OneDrive\Doctorado\Study 1\data\Retest Bkp\Day 1\Sart\"
strFile = Dir(strDir & "*.csv")
Do While strFile <> ""
Set wb = Workbooks.Open(Filename:=strDir & strFile, Local:=True)
With wb
.SaveAs Replace(wb.FullName, ".csv", ".xlsx"), 51
.Close True
End With
Set wb = Nothing
strFile = Dir
Loop
End Sub