Is it possible to read and write csv files using FileSystemObject in VBA?
It certainly is.
Basic syntax such as
Set objFSO = CreateObject("scripting.filesystemobject")
'create a csv file
Set objTF = objFSO.createtextfile("C:\test\myfile.csv", True, False)
'open an existing csv file with writing ability
Set objTF = objFSO.OpenTextFile("C:\test\myfile.csv", 8)
will create/open a CSV with FSO.
The CSV can then be modified by writing to it
While this is an Excel example you can use the same technique to write records from Outlook, Access, Word etc
Const sFilePath = "C:\test\myfile.csv"
Const strDelim = ","
Sub CreateCSV_FSO()
Dim objFSO
Dim objTF
Dim ws As Worksheet
Dim lRow As Long
Dim lCol As Long
Dim strTmp As String
Dim lFnum As Long
Set objFSO = CreateObject("scripting.filesystemobject")
Set objTF = objFSO.createtextfile(sFilePath, True, False)
For Each ws In ActiveWorkbook.Worksheets
'test that sheet has been used
Set rng1 = ws.UsedRange
If Not rng1 Is Nothing Then
'only multi-cell ranges can be written to a 2D array
If rng1.Cells.Count > 1 Then
X = ws.UsedRange.Value2
'The code TRANSPOSES COLUMNS AND ROWS by writing strings column by column
For lCol = 1 To UBound(X, 2)
'write initial value outside the loop
strTmp = IIf(InStr(X(1, lCol), strDelim) > 0, """" & X(1, lCol) & """", X(1, lCol))
For lRow = 2 To UBound(X, 1)
'concatenate long string & (short string with short string)
strTmp = strTmp & (strDelim & IIf(InStr(X(lRow, lCol), strDelim) > 0, """" & X(lRow, lCol) & """", X(lRow, lCol)))
Next lRow
'write each line to CSV
objTF.writeline strTmp
Next lCol
Else
objTF.writeline IIf(InStr(ws.UsedRange.Value, strDelim) > 0, """" & ws.UsedRange.Value & """", ws.UsedRange.Value)
End If
End If
Next ws
objTF.Close
Set objFSO = Nothing
MsgBox "Done!", vbOKOnly
End Sub
It seems possible.
The FileSystemObject (FSO) provides an API to access the Windows filesystem, providing access to files, drives, text streams etc. The FSO is embedded within the Microsoft Scripting run-time, and is available to stand-alone applications (coded using Visual Basic, for example), to web page designers using VBScript or JScript and to users of Microsoft Office applications using Visual Basic for Applications (VBA).
Some references:-
Using The FileSystemObject With VB and VBA
How do I use FileSystemObject in VBA?
Related
I've managed to piece together this VBA which takes data from excel and turns it into .txt flat file. It works exactly as I need, but I would like to alter it so that the end result is saved as Unicode as opposed to ANSI.
I've done some reading and the answer I keep coming back to is to use FileSystemObject. I found a VBA on here that does the job perfectly, but I can't for the life of me work out how to incorporate it into my existing code. Any chance someone could throw me some pointers?
This is my current code:
' Defines everything first. So, from B2, across and down.
LastRow = Sheets("Pricing").Range("B" & Rows.Count).End(xlUp).Row
LastColumn = Sheets("Pricing").Cells(2, Columns.Count).End(xlToLeft).Column
' File name, path to save to and delimiter.
file = Sheets("Pricing").TextBox1 & ".txt"
If TextBox1.Value = "" Then MsgBox "What we calling it genius?", vbQuestion
If TextBox1.Value = "" Then Exit Sub
Path = "C:\Users\me.me\Desktop\Files\"
Delimeter = "|"
' The magic bit.
myFileName = Path & file
FN = FreeFile
Open myFileName For Output As #FN
For Row = 2 To LastRow
For Column = 2 To LastColumn
If Column = 2 Then Record = Trim(Cells(Row, Column)) Else Record = Record & Delimeter & Trim(Cells(Row, Column))
Next Column
Print #FN, Record
Next Row
Close #FN
MsgBox "BOOM! LOOKIT ---> " & myFileName
' Opens the finished file.
Dim fso As Object
Dim sfile As String
Set fso = CreateObject("shell.application")
sfile = "C:\Users\me.me\Desktop\Files\" & Sheets("Pricing").TextBox1 & ".txt"
fso.Open (sfile)
And this is what I've been trying to incorporate (HUGE thanks to MarkJ for posting this on another question):
Dim fso As Object, MyFile As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set MyFile = fso.CreateTextFile("c:\testfile.txt", False,True) 'Unicode=True'
MyFile.WriteLine("This is a test.")
MyFile.Close
I just can't get it to work.
Please, test the next code. You did not answer my clarification question, but it works using the above comment assumptions. It take the file name, from an activeX text box situated on the sheet to be processed. The code should be faster than yours for big ranges, avoiding to iterate between all cells:
Sub SaveAsUnicode()
Dim shP As Worksheet, iRow As Long, Record As String, Delimeter As String
Dim file As String, myFileName As String, path As String, txtB As MSForms.TextBox
Dim rng As Range, lastCell As Range, arr, arrRow
Dim fso As Object, MyFile As Object, shApp As Object
Set shP = Worksheets("Pricinig")
Set txtB = shP.OLEObjects("TextBox1").Object 'it sets an activeX sheet text box
file = txtB.Text & ".txt"
If txtB.value = "" Then MsgBox "What we calling it genius?", vbQuestion: Exit Sub
Set lastCell = shP.cells.SpecialCells(xlCellTypeLastCell) 'last cell of the sheet
Set rng = shP.Range("A2", lastCell) 'create the range to be processed
arr = rng.value 'put the range in an array
path = "C:\Users\me.me\Desktop\Files\" 'take care to adjust the path!
myFileName = path & file
Delimeter = "|"
Set fso = CreateObject("Scripting.FileSystemObject")
Set MyFile = fso.CreateTextFile(myFileName, False, True) 'open the file to write Unicode:
For iRow = 1 To UBound(arr) 'itereate between the array rows
arrRow = Application.Index(arr, iRow, 0) 'make a slice of the currrent arrray row
Record = Join(arrRow, Delimeter) 'join the iD obtained array, using the set Delimiter
MyFile.WriteLine (Record) 'write the row in the Unicode file
Next iRow
MyFile.Close 'close the file
'open the obtained Unicode file:
Set shApp = CreateObject("shell.application")
shApp.Open (myFileName)
End Sub
I tested the above code on a sheet using characters not supported in ANSI and it works as expected.
Please, send some feedback after testing it, or if my assumptions after reading your question are not correct...
#FaneDuru, this is what I ended up putting together, it's working great for me. Thanks again for all of your help.
Private Sub FlatButton_Click()
'Does all the setup stuff.
Dim fso As Object, MyFile As Object
Dim MyFileName As String
Dim txtB As MSForms.TextBox
Set shP = Worksheets("Pricing")
Set txtB = shP.OLEObjects("TextBox1").Object
file = txtB.Text & ".txt"
If txtB.Value = "" Then MsgBox "What we calling it?", vbQuestion: Exit Sub
' Defines the range. So, from B2, across and down.
LastRow = Sheets("Pricing").Range("B" & Rows.Count).End(xlUp).Row
LastColumn = Sheets("Pricing").Cells(2, Columns.Count).End(xlToLeft).Column
'File details.
path = "C:\Users\me.me\Blah\Blah\"
MyFileName = path & file
Delimeter = "|"
' The magic bit.
Set fso = CreateObject("Scripting.FileSystemObject")
Set MyFile = fso.CreateTextFile(MyFileName, False, True) '<==== This defines the Unicode bit.
For Row = 2 To LastRow
For Column = 2 To LastColumn
If Column = 2 Then Record = Trim(Cells(Row, Column)) Else Record = Record & Delimeter & Trim(Cells(Row, Column))
Next Column
MyFile.WriteLine (Record)
Next Row
MyFile.Close
MsgBox "BOOM! ---> " & MyFileName
'Option to open the finished product.
If ActiveSheet.CheckBox2.Value = True Then
Set shApp = CreateObject("shell.application")
shApp.Open (MyFileName)
End If
End Sub
The code I have loops through a folder that has 100+ files (with more files being added daily) and copies files, data, etc. Every file that I loop through ends up in the VBA Project Explorer as you can see from the picture. This is really slowing down the run time of my code. Is there any way I can prevent each workbook from being added to the Project Explorer? Also, I haven't run my code with the optimize subroutines that I call to because I added those after running my original code (and now the editor is basically frozen). I attached my code as well as the picture of my issue below!
Sub TransferSAPCLData_Click()
'Code Optimization
Call OptimizeCode_Begin
'Declaring and Setting Variables
Dim fso As Scripting.FileSystemObject
Set fso = New Scripting.FileSystemObject
Dim MyDir As String
Dim fil As Scripting.file
Dim FolderSource As Scripting.Folder
Dim FolderPathDest As String, wbDest As Workbook, wsDest As Worksheet
Dim wbSource As Workbook, wsSource As Worksheet
Dim lrDest As Long, fileDest As String, lrSource As Long
Dim CurrentFile As String
Dim fileSource As String
MyDir = "C:\Users\quirk\Desktop\Cory Project\Wave 1A Content\SAPCL Spreadsheets\SAPCL Raw Data Files"
'Defining destination characteristics
FolderPathDest = "C:\Users\quirk\Desktop\Cory Project\Wave 1A Content\Master SAPCL Folder"
fileDest = "C:\Users\quirk\Desktop\Cory Project\Wave 1A Content\Master SAPCL Folder\Function Master File.xlsm"
'Workbooks.Open Filename:=fileDest
Set wbDest = ActiveWorkbook ' Workbooks("MASTER.xlsx")
Set wsDest = wbDest.Worksheets("Sheet1")
'Looping through files
Set FolderSource = fso.GetFolder(MyDir)
For Each fil In FolderSource.Files
Debug.Print fil.Name
CurrentFile = fil.Name
If Not fso.FileExists(FolderPathDest & "\" & fil.Name) Then
fso.CopyFile _
Source:=MyDir & "\" & fil.Name _
, Destination:=FolderPathDest & "\" & fil.Name
fileSource = MyDir & "\" & fil.Name
Workbooks.Open Filename:=fileSource '
ActiveWindow.Visible = False
Set wbSource = Workbooks(CurrentFile)
Set wsSource = wbSource.Worksheets(1)
lrSource = wsSource.Range("A" & wsSource.Rows.Count).End(xlUp).Row
lrDest = wsDest.Range("A" & wsDest.Rows.Count).End(xlUp).Row + 1
wsSource.Range("A2:V" & lrSource).Copy Destination:=wsDest.Range("A" & lrDest)
End If
Next fil
'Optimize Code
Call OptimizeCode_End
End Sub
I am trying to upload a dataset from excel to an access database using the following code.
However i keep getting the Run time error 3078- Application defined or object defined error. i am using the dao for this and have added the follwing references:
Microsoft office 16.0 access database engine object library,
Microsoft access 16.0 library.
i am unable to add the Microsoft DAO 3.6 object library (Name conflicts with existing module, project or object libary
here is the code:
Sub access_upload()
Dim strMyPath As String, strDBName As String, strDB As String
Dim i As Long, n As Long, lLastRow As Long, lFieldCount As Long
Dim daoDB As DAO.Database
Dim recSet As DAO.Recordset
strDBName = "Database8.accdb"
'presume to be in the same location as the host workbook:
strMyPath = ThisWorkbook.Path
strDB = strMyPath & "\" & strDBName
Set daoDB = DBEngine.Workspaces(0).OpenDatabase(strDB)
Dim ws As Worksheet
Set ws = ActiveWorkbook.Sheets("Sheet2")
Set recSet = daoDB.OpenRecordset("Database8")
lFieldCount = recSet.Fields.Count
lLastRow = ws.Cells(Rows.Count, "A").End(xlUp).Row
For i = 2 To lLastRow
recSet.AddNew
For n = 0 To lFieldCount - 1
recSet.Fields(n).Value = ws.Cells(i, n + 1)
Next n
recSet.Update
Next i
recSet.Close
daoDB.Close
Set daoDB = Nothing
Set recSet = Nothing
End Sub
Please let me know what i am missing here. Thanks!
From Excel to Access . . .
Dim strPathFile As String, strFile As String, strPath As String
Dim strTable As String
Dim blnHasFieldNames As Boolean
' Change this next line to True if the first row in EXCEL worksheet
' has field names
blnHasFieldNames = False
' Replace C:\Documents\ with the real path to the folder that
' contains the EXCEL files
strPath = "C:\Documents\"
' Replace tablename with the real name of the table into which
' the data are to be imported
strTable = "tablename"
strFile = Dir(strPath & "*.xls")
Do While Len(strFile) > 0
strPathFile = strPath & strFile
DoCmd.TransferSpreadsheet acImport, acSpreadsheetTypeExcel9, _
strTable, strPathFile, blnHasFieldNames
' Uncomment out the next code step if you want to delete the
' EXCEL file after it's been imported
' Kill strPathFile
strFile = Dir()
Loop
also if the path and excel name are fixed; you can step thru the import manually using the External features from the ribbon - at the end of which will be a prompt to save those steps as a defined import.
you can then rerun the import just by a docmd to run the saved import
I want to open, using VBA, a workbook from a certain path that includes a number, for example 2. Any variation I tried is not working.
The name of the workbook is in Hebrew except for the number, so I want the VBA code to base the file name on the number to open the file.
I have 4 letters in hebrew before the number. In Hebrew we write from right to left.
Here is my code:
Set WB1 = Workbooks.Open("C:\RESULTS\" 2 & ".xlsx")
Thanks for helping.
Try this
Dim sFound As String, fPath As String
fPath = "C:\RESULTS\"
sFound = Dir(fPath & "*2*.xlsx") 'get the first file in dir
If sFound <> "" Then
Set WB1 = Workbooks.Open(fPath & sFound)
End If
This works for me:
Option Explicit
Sub TestMe()
Dim objFSO As Object
Dim objFolder As Object
Dim objFile As Object
Dim wbs As Workbook
Dim strExtension As String
Dim lngNumber As String
Dim lngAdditional As Long
Dim lngLenFile As Long
strExtension = ".xlsx"
lngNumber = 20
lngAdditional = 4
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder("C:\Users\Desktop\")
lngLenFile = Len(strExtension) + Len(lngNumber) + lngAdditional
For Each objFile In objFolder.Files
If Left(objFile.Name, Len(lngNumber)) = lngNumber And _
Right(objFile, Len(strExtension)) = strExtension And _
Len(objFile.Name) = lngLenFile Then
Debug.Print objFile.Name
Set wbs = Workbooks.Open(objFile)
End If
Next objFile
End Sub
The idea of the code is to make it flexible, thus, lngNumber and strExtension are added. It checks always for the size, as well as for right and left. Thus 24Some.xlsx would be different than 2Some.xlsx.
Debug.Print is added to see the file that is opened.
lngAdditional is added, for the additional 4 chars.
I want to move files to another folder from an Excel file (listfiles.xlsx) which contains paths of files in column A. The code below didn't work for me, can you help me please?
Sub movefile1()
Dim fso As FileSystemObject
Dim i As Long
Dim worksh As Worksheet
Dim workboo As Workbook
Set fso = CreateObject("scripting.filesystemobject")
Destination = "C:\Users\Desktop\Folder"
Set workboo = Workbooks.Open("C:\Users\TOSHIBA\Desktop\list_files.xlsx")
Set worksh = Worksheets("Listing")
numRows = worksh.Range("A" & Rows.Count).End(xlUp).Row
workboo.Windows(1).Visible = False
For i = 2 To numRows
Filepath = worksh.Range("A" & i).Value
fso.CopyFile Filepath, Destination
Next
End Sub
I changed the code but the fso.CopyFile Filepath, Destination does not work. They say permission refused
Place the line numRows = .Range("A" & .Rows.Count).End(xlUp).Row before the loop, otherwise the loop won't be executed at all