I am glad to be here with great programmers and hope I will learn a lot. I am also new in this kind of programming so I am sorry for any inconvenience.
I am using the vba code below to transfer my files from XLS into CSV. After it translates the xls file into csv format, it saves automatically my newly created csv file in the same directory as my original xls file.
I would like to have a Save As option for my csv filename
Thank you in advance.
' ---------------------- Directory Choosing Helper Functions -----------------------
' Excel and VBA do not provide any convenient directory chooser or file chooser
' dialogs, but these functions will provide a reference to a system DLL
' with the necessary capabilities
Private Type BROWSEINFO ' used by the function GetFolderName
hOwner As Long
pidlRoot As Long
pszDisplayName As String
lpszTitle As String
ulFlags As Long
lpfn As Long
lParam As Long
iImage As Long
End Type
Private Declare Function SHGetPathFromIDList Lib "shell32.dll" _
Alias "SHGetPathFromIDListA" (ByVal pidl As Long, ByVal pszPath As String) As Long
Private Declare Function SHBrowseForFolder Lib "shell32.dll" _
Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long
Function GetFolderName(Msg As String) As String
' returns the name of the folder selected by the user
Dim bInfo As BROWSEINFO, path As String, r As Long
Dim X As Long, pos As Integer
bInfo.pidlRoot = 0& ' Root folder = Desktop
If IsMissing(Msg) Then
bInfo.lpszTitle = "Select a folder."
' the dialog title
Else
bInfo.lpszTitle = Msg ' the dialog title
End If
bInfo.ulFlags = &H1 ' Type of directory to return
X = SHBrowseForFolder(bInfo) ' display the dialog
' Parse the result
path = Space$(512)
r = SHGetPathFromIDList(ByVal X, ByVal path)
If r Then
pos = InStr(path, Chr$(0))
GetFolderName = Left(path, pos - 1)
Else
GetFolderName = ""
End If
End Function
'---------------------- END Directory Chooser Helper Functions ----------------------
Public Sub DoTheExport()
Dim FName As Variant
Dim Sep As String
Dim wsSheet As Worksheet
Dim nFileNum As Integer
Dim csvPath As String
Sep = ";"
csvPath = Application.ActiveWorkbook.path
Dim brojac As Integer
brojac = 0
For Each wsSheet In Worksheets
If brojac > 0 Then Exit For
wsSheet.Activate
nFileNum = FreeFile
Open csvPath & "\" & _
Left(ActiveWorkbook.Name, Len(ActiveWorkbook.Name) - 5) & ".csv" For Output As #nFileNum ' wsSheet.Name
ExportToTextFile CStr(nFileNum), Sep, False
Close nFileNum
brojac = brojac + 1
Next wsSheet
End Sub
Public Sub ExportToTextFile(nFileNum As Integer, _
Sep As String, SelectionOnly As Boolean)
Dim WholeLine As String
Dim RowNdx As Long
Dim ColNdx As Integer
Dim StartRow As Long
Dim EndRow As Long
Dim StartCol As Integer
Dim EndCol As Integer
Dim CellValue As String
Application.ScreenUpdating = False
On Error GoTo EndMacro:
If SelectionOnly = True Then
With Selection
StartRow = .Cells(1).Row
StartCol = .Cells(1).Column
EndRow = .Cells(.Cells.Count).Row
EndCol = .Cells(.Cells.Count).Column
End With
Else
With ActiveSheet.UsedRange
StartRow = .Cells(1).Row
StartCol = .Cells(1).Column
EndRow = .Cells(.Cells.Count).Row
EndCol = .Cells(.Cells.Count).Column
End With
End If
For RowNdx = StartRow To EndRow
WholeLine = ""
For ColNdx = StartCol To EndCol
If Cells(RowNdx, ColNdx).Value = "" Then
CellValue = ""
Else
CellValue = Cells(RowNdx, ColNdx).Value
End If
WholeLine = WholeLine & CellValue & Sep
Next ColNdx
WholeLine = Left(WholeLine, Len(WholeLine) - Len(Sep))
Print #nFileNum, WholeLine
Next RowNdx
EndMacro:
On Error GoTo 0
Application.ScreenUpdating = True
End Sub
Probably the problem is here. This part of code has to be re-writen or corrected.
This is the main function which calls other ones.
Public Sub DoTheExport()
Dim FName As Variant
Dim Sep As String
Dim wsSheet As Worksheet
Dim nFileNum As Integer
Dim csvPath As String
Sep = ";"
csvPath = Application.ActiveWorkbook.path
Dim brojac As Integer
brojac = 0
For Each wsSheet In Worksheets
If brojac > 0 Then Exit For
wsSheet.Activate
nFileNum = FreeFile
Open csvPath & "\" & _
Left(ActiveWorkbook.Name, Len(ActiveWorkbook.Name) - 5) & ".csv" For Output As #nFileNum ' wsSheet.Name
ExportToTextFile CStr(nFileNum), Sep, False
Close nFileNum
brojac = brojac + 1
Next wsSheet
End Sub
This updated code gives you a SaveAs name option (with a default as WorkbookName.csv)
More efficient code using variant arrays to make your csv below.
These are the three key updated lines:
strFileName = Application.GetSaveAsFilename(Left$(ActiveWorkbook.Name, Len(ActiveWorkbook.Name) - 5), "CSV (Comma delimited) (*.csv), *.csv")
If strFileName = "False" Then Exit Sub
Open strFileName For Output As #nFileNum
updated code
Public Sub DoTheExport()
Dim FName As Variant
Dim Sep As String
Dim wsSheet As Worksheet
Dim nFileNum As Integer
Dim csvPath As String
Dim strFileName As String
Sep = ";"
csvPath = Application.ActiveWorkbook.path
Dim brojac As Long
brojac = 0
For Each wsSheet In Worksheets
If brojac > 0 Then Exit For
wsSheet.Activate
nFileNum = FreeFile
strFileName = Application.GetSaveAsFilename(Left$(ActiveWorkbook.Name, Len(ActiveWorkbook.Name) - 5), "CSV (Comma delimited) (*.csv), *.csv")
If strFileName = "False" Then Exit Sub
Open strFileName For Output As #nFileNum
ExportToTextFile CStr(nFileNum), Sep, False
Close nFileNum
brojac = brojac + 1
Next wsSheet
End Sub
more efficient csv code
From Creating and Writing to a CSV File Using Excel VBA
This code must be run from a regular VBA Code Module. Otherwise the code will cause an error if users try to run it from the ThisWorkbook or Sheet Code panes given the usage of Const.
It is worth noting that the ThisWorkbook and Sheet code sections should be reserved for Event coding only, "normal" VBA should be run from standard Code Modules.
Please note that for purposes of the sample code, the file path of the CSV output file is "hard-coded" as: C:\test\myfile.csv at the top of the code. You will probably want to set the output file programmatically, for instance as a function parameter.
As mentioned earlier; For example purposes, this code TRANSPOSES COLUMNS AND ROWS; that is, the output file contains one CSV row for each column in the selected range. Normally, CSV output would be row-by-row, echoing the layout visible on screen, but I wanted to demonstrate that generating the output by using VBA code provides options beyond what is available by, for instance, using the Save As... CSV Text menu option.
code
Const sFilePath = "C:\test\myfile.csv"
Const strDelim = ","
Sub CreateCSV_Output()
Dim ws As Worksheet
Dim rng1 As Range
Dim X
Dim lRow As Long
Dim lCol As Long
Dim strTmp As String
Dim lFnum As Long
lFnum = FreeFile
Open sFilePath For Output As lFnum
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
Print #lFnum, strTmp
Next lCol
Else
Print #lFnum, IIf(InStr(ws.UsedRange.Value, strDelim) > 0, """" & ws.UsedRange.Value & """", ws.UsedRange.Value)
End If
End If
Next ws
Close lFnum
MsgBox "Done!", vbOKOnly
End Sub
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
Related
I am using a VBA sub which works inconsistently. The sub is based on a previous Stack Overflow thread answer I found which when it works is perfect. Copy Data from Excel to Notepad.
Sub CopyEventtoNotepad()
'Dim rngData As Range
Dim strData As String
Dim strTempFile As String
Dim strPath As String
strPath = Environ("USERPROFILE") & "\Desktop\HBT.txt"
Set Meeting = Worksheets("Patient").Range("CN21:CO55")
Set MeetingComments = Worksheets("Patient").Range("CN21:CO58")
Set Phone = Worksheets("Patient").Range("CS21:CT33")
Set PhoneComments = Worksheets("Patient").Range("CS21:CT36")
If Worksheets("Patient").Range("BB9").Value = 1 Then MeetingComments.Copy
If Worksheets("Patient").Range("BB9").Value = 2 Then Meeting.Copy
If Worksheets("Patient").Range("BB9").Value = 3 Then PhoneComments.Copy
If Worksheets("Patient").Range("BB9").Value = 4 Then Phone.Copy
' get the clipboard data
' magic code for is for early binding to MSForms.DataObject
With CreateObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
.GetFromClipboard
strData = .GetText
End With
' write to temp file
strTempFile = strPath
With CreateObject("Scripting.FileSystemObject")
' true to overwrite existing temp file
.CreateTextFile(strTempFile, True).Write strData
End With
' open notepad with tempfile
Shell "cmd /c ""notepad.exe """ & strTempFile & """", vbHide
End Sub
The runtime error occurs at the following line:
.CreateTextFile(strTempFile, True).Write strData
I have been trying to identify what the variable factor is that triggers the runtime error 5 for weeks. I can't find a pattern.
Thanks
Copy Range to String
The other day, someone mentioned in the comments that Dao is not working supposedly due to a Windows or Office update.
Anyways, here's a simple workaround that may serve you well for such small ranges.
Option Explicit
Sub CopyEventToNotepad()
Dim rgAddresses As Variant
rgAddresses = VBA.Array("CN21:CO55", "CN21:CO58", "CS21:CT33", "CS21:CT36")
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim ws As Worksheet: Set ws = wb.Worksheets("Patient")
Dim rg As Range: Set rg = ws.Range(rgAddresses(ws.Range("BB9").Value - 1))
Dim FilePath As String
FilePath = Environ("USERPROFILE") & "\Desktop\HBT.txt"
Dim RangeString As String: RangeString = StringRangeRows(rg)
With CreateObject("Scripting.FileSystemObject")
.CreateTextFile(FilePath, True).Write RangeString
End With
Shell "cmd /c ""notepad.exe """ & FilePath & """", vbHide
End Sub
Function StringRangeRows( _
ByVal rg As Range, _
Optional ByVal CellDelimiter As String = vbTab, _
Optional ByVal LineDelimiter As String = vbLf) _
As String
Dim cLen As Long: cLen = Len(CellDelimiter)
Dim arg As Range, rrg As Range, rCell As Range, RangeString As String
For Each arg In rg.Areas
For Each rrg In arg.Rows
For Each rCell In rrg.Cells
RangeString = RangeString & CStr(rCell.Value) & CellDelimiter
Next rCell
RangeString = Left(RangeString, Len(RangeString) - cLen) _
& LineDelimiter
Next rrg
Next arg
StringRangeRows = Left(RangeString, Len(RangeString) - Len(LineDelimiter))
End Function
I have made the following code where the aim is to save two ranges into a CSV file:
Sub Export_range_to_CSV()
Dim myCSVFileName As String
Dim myWB As Workbook
Dim tempWB As Workbook
Dim range1 As Range
Dim range2 As Range
Set range1 = Sheets("sheet1").Range("G2:G4")
Set range2 = Sheets("sheet1").Range("G5:H53")
Application.DisplayAlerts = False
On Error GoTo err
Set myWB = ThisWorkbook
myCSVFileName = "filepath" & "\" & "name" & VBA.Format(VBA.Now, "yyyymmdd_hhmm") & ".csv"
range1.Copy
Set tempWB = Application.Workbooks.Add(1)
With tempWB
.Sheets(1).Range("A1").PasteSpecial xlPasteValues
range2.Copy
.Sheets(1).Range("A4").PasteSpecial xlPasteValues
.SaveAs Filename:=myCSVFileName, FileFormat:=xlCSV, CreateBackup:=False
.Close
End With
err:
Application.DisplayAlerts = True
End Sub
The code above does the job, but for range1 it has commas at the end of the string when saved as CSV. I need to remove these in order for a job downstream to work. How do I get rid of the commas at the end of range1?
This is how it looks once saved as the CSV file:
range1
- # X=Y, <- need to remove these commas
- # Z=U,
- # M=Q,
range2
- datetime,quantity
- 2021-03-05 23:00:00+00:00,17
- 2021-03-05 23:30:00+00:00,17
- 2021-03-06 00:00:00+00:00,17
- 2021-03-06 00:30:00+00:00,17
I think the problem comes from range1 only having a single column and as soon as range2 comes into play it assumes range1 should be two columns as well.
The last column is calculated by checking the last column of both the ranges. Whichever is higher will be taken. Let me explain it.
Let's say the data is till column J
Set range1 = Sheets("sheet1").Range("G2:G4")
Set range2 = Sheets("sheet1").Range("G5:J53")
Then in this scenario, there will be 3 commas added. Similarly if the last column is K in range2 and last column is H in range1 then there will be 3 commas added to the 1st range.
The same holds true when you reverse the range
Set range1 = Sheets("sheet1").Range("G5:J53")
Set range2 = Sheets("sheet1").Range("G2:G4")
Now the 2nd range will have extra commas
Solution
Read the data in an array and then remove the last comma. So once your Csv file is written, pass the file to this procedure and it will take care of the rest
The below code reads the csv in an array in one go and then checks every line if it has a , on the right. And if it has then it removes it. Finally it deletes the old csv and writes the new file by putting the array in the text file in one go. I have commented the code so you should not have a problem understanding it. But if you do then simply ask.
'~~> Example usage
Sub Sample()
CleanCsv "C:\Users\Siddharth Rout\Desktop\aaa.txt"
End Sub
'~~> Cleans csv
Sub CleanCsv(fl As String)
Dim MyData As String, strData() As String
Dim i As Long
'~~> Read the file in one go into an array
Open fl For Binary As #1
MyData = Space$(LOF(1))
Get #1, , MyData
Close #1
strData() = Split(MyData, vbCrLf)
'~~> Check for "," and remove
For i = LBound(strData) To UBound(strData)
If Right(strData(i), 1) = "," Then
Do While Right(strData(i), 1) = ","
strData(i) = Left(strData(i), Len(strData(i)) - 1)
Loop
End If
Next i
'~~> Kill old file
Kill fl
'~~> Output the array in one go into a text file
Dim ff As Long
ff = FreeFile
Open fl For Binary As #ff
Put #ff, , Join(strData, vbCrLf)
Close #ff
End Sub
Remove Trailing Comma
You run exportRangesToCSV, while removeTrailingCommaInTextFile is being called near the end, and removeTrailingComma is being called by removeTrailingCommaInTextFile.
I tested it and it works, but keep in mind that I know very little about manipulating text files (2nd procedure) and that this is more or less the first Regex I've ever written (3rd procedure). It took me 'ages' to write them (not complaining). The 1st procedure is where I'm 'at home'.
Note the example of a classic error-handling routine in the 2nd procedure (yours is unacceptable: you're missing the Resume part). You could easily apply it to the 1st procedure.
Don't forget to adjust the values in the constants section.
The Code
Option Explicit
Sub exportRangesToCSV()
Const sName As String = "Sheet1"
Const sAddr As String = "G2:G4,G5:H53"
Const dFolderPath As String = "C:\Test"
Const dLeftBaseName As String = "Name"
Const dTimeFormat As String = "yyyymmdd_hhmm"
Const dFileExtension As String = ".csv"
Const dAddr As String = "A1"
Dim wb As Workbook: Set wb = ThisWorkbook
Dim rg As Range: Set rg = wb.Worksheets(sName).Range(sAddr)
Dim dFilePath As String
dFilePath = dFolderPath & "\" & dLeftBaseName _
& VBA.Format(VBA.Now, dTimeFormat) & dFileExtension
Application.ScreenUpdating = False
With Workbooks.Add()
Dim dCell As Range: Set dCell = .Worksheets(1).Range(dAddr)
Dim srg As Range
For Each srg In rg.Areas
dCell.Resize(srg.Rows.Count, srg.Columns.Count).Value = srg.Value
Set dCell = dCell.Offset(srg.Rows.Count)
Next srg
Application.DisplayAlerts = False
.SaveAs dFilePath, xlCSV
Application.DisplayAlerts = True
.Close False
End With
Application.ScreenUpdating = True
removeTrailingCommaInTextFile dFilePath, True
'wb.FollowHyperlink dFolderPath
End Sub
Sub removeTrailingCommaInTextFile( _
ByVal FilePath As String, _
Optional ByVal removeAllOccurrences As Boolean = False)
Const ProcName As String = "removeTrailingCommaInTextFile"
On Error GoTo clearError
Dim TextFile As Long: TextFile = FreeFile
Dim TempString As String
Open FilePath For Input As TextFile
TempString = Input(LOF(TextFile), TextFile)
Close TextFile
Open FilePath For Output As TextFile
Print #TextFile, removeTrailingComma(TempString, removeAllOccurrences)
Close TextFile
ProcExit:
Exit Sub
clearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & err.Number & "':" & vbLf _
& " " & err.Description
Resume ProcExit
End Sub
Function removeTrailingComma( _
ByVal SearchString As String, _
Optional ByVal removeAllOccurrences As Boolean = False) _
As String
With CreateObject("VBScript.RegExp")
.Global = True
.MultiLine = True
If removeAllOccurrences Then
.Pattern = ",+$"
Else
.Pattern = ",$"
End If
removeTrailingComma = .Replace(SearchString, "")
End With
End Function
Edit
This solution will write directly to the text file without exporting. It may become slow if there are too many cells.
Arrays
Sub exportRangesToCSVArrays()
Const sName As String = "Sheet1"
Const sAddr As String = "G2:G4,G5:H53"
Const dFolderPath As String = "C:\Test"
Const dLeftBaseName As String = "Name"
Const dTimeFormat As String = "yyyymmdd_hhmm"
Const dFileExtension As String = ".csv"
Const dAddr As String = "A1"
Const Delimiter As String = ","
Dim wb As Workbook: Set wb = ThisWorkbook
Dim rg As Range: Set rg = wb.Worksheets(sName).Range(sAddr)
Dim aCount As Long: aCount = rg.Areas.Count
Dim Data As Variant: ReDim Data(1 To aCount)
Dim rData() As Long: ReDim rData(1 To aCount)
Dim cData() As Long: ReDim cData(1 To aCount)
Dim OneCell As Variant: ReDim OneCell(1 To 1, 1 To 1)
Dim srg As Range
Dim srCount As Long, scCount As Long
Dim drCount As Long, dcCount As Long
Dim n As Long
For Each srg In rg.Areas
n = n + 1
srCount = srg.Rows.Count: scCount = srg.Columns.Count
rData(n) = srCount: cData(n) = scCount
If srCount > 1 Or scCount > 1 Then
Data(n) = srg.Value
Else
Data(n) = OneCell: Data(1, 1) = srg.Value
End If
drCount = drCount + srCount
If scCount > dcCount Then
dcCount = scCount
End If
Next srg
Dim Result() As String: ReDim Result(1 To drCount)
Dim r As Long, i As Long, j As Long
For n = 1 To aCount
For i = 1 To rData(n)
r = r + 1
For j = 1 To cData(n)
Result(r) = Result(r) & CStr(Data(n)(i, j)) & Delimiter
Next j
Result(r) = removeTrailingComma(Result(r), True)
Next i
Next n
Dim dFilePath As String
dFilePath = dFolderPath & "\" & dLeftBaseName _
& VBA.Format(VBA.Now, dTimeFormat) & dFileExtension
Dim TextFile As Long: TextFile = FreeFile
Dim TempString As String
Open dFilePath For Output As TextFile
Print #TextFile, Join(Result, vbLf)
Close TextFile
'wb.FollowHyperlink dFolderPath
End Sub
I am trying to loop through all named ranges in a workbook and save each object as a separate CSV file. I hacked the code below and it loops through all named ranges and it creates a bunch of CSV files, but it doesn't actuall export any data to any of those CSV files. What am I missing here?
Sub ExportAllNamedRanges()
Dim myCSVFileName As String
Dim myWB As Workbook
Dim rngToSave As Range
Dim fNum As Integer
Dim csvVal As String
Dim intCounter As Integer
Dim nmTemp As Name
Dim nm
Set myWB = ThisWorkbook
For Each nm In ThisWorkbook.Names
Debug.Print nm.Name
myCSVFileName = myWB.Path & "\" & nm.Name & ".csv"
csvVal = ""
fNum = FreeFile
Set rngToSave = Range(nm.Name)
Open myCSVFileName For Output As #fNum
For i = 1 To rngToSave.Rows.Count
For j = 1 To rngToSave.Columns.Count
csvVal = csvVal & Chr(34) & rngToSave(i, j).Value & Chr(34) & ","
Next
Print #fNum, Left(csvVal, Len(csvVal) - 2)
csvVal = ""
Next
Close #fileNumber
Next nm
End Sub
I figured it out. The code below works fine.
Sub ExportAllNamedRanges()
Dim myCSVFileName As String
Dim myWB As Workbook
Dim rngToSave As Range
Dim fNum As Integer
Dim csvVal As String
Dim intCounter As Integer
Dim nmTemp As Name
Dim nm
Set myWB = ThisWorkbook
For Each nm In ThisWorkbook.Names
Debug.Print nm.Name
Dim filename As String, lineText As String
Dim myrng As Range, i, j
filename = ThisWorkbook.Path & "\" & nm.Name & ".csv"
Open filename For Output As #1
Set myrng = Range(nm.Name)
For i = 1 To myrng.Rows.Count
For j = 1 To myrng.Columns.Count
lineText = IIf(j = 1, "", lineText & ",") & myrng.Cells(i, j)
Next j
Print #1, lineText
Next i
Close #1
Next nm
End Sub
Also, here is a nice and simple way to list all named ranges in a workbook.
Sub ListAllNamedRanges()
Dim nm As Name, n As Long, y As Range, z As Worksheet
Application.ScreenUpdating = False
Set z = ActiveSheet
n = 2
With z
.[A1:G65536].ClearContents
.[A1:C1] = [{"Name","Sheet Name","Range"}]
For Each nm In ActiveWorkbook.Names
.Cells(n, 1) = nm.Name
.Cells(n, 2) = Range(nm).Parent.Name
.Cells(n, 3) = nm.RefersToRange.Address(False, False)
n = n + 1
Next nm
End With
Set y = z.Range("C2:C" & z.[C65536].End(xlUp).Row)
y.TextToColumns Destination:=z.[C2], DataType:=xlDelimited, _
OtherChar:=":", FieldInfo:=Array(Array(1, 1), Array(2, 1))
[A:C].EntireColumn.AutoFit
Application.ScreenUpdating = True
End Sub
Save batch files as csv from excel.
VBA separates one Excel sheet of data into separate files, after every 833th row.
Now I need these files to be csvs and not Excels. How can I save directly to .csv (separated by comma) files?
I have made appropriate VBA to save into Excel (xml), but not csvs. I need CSVs.
Sub Macro1()
Dim rLastCell As Range
Dim rCells As Range
Dim strName As String
Dim lLoop As Long, lCopy As Long
Dim wbNew As Workbook
With ThisWorkbook.Sheets(1)
Set rLastCell = .Cells.Find(What:="*", After:=[A1], SearchDirection:=xlPrevious)
For lLoop = 1 To rLastCell.Row Step 833
lCopy = lCopy + 1
Set wbNew = Workbooks.Add
.Range(.Cells(lLoop, 1), .Cells(lLoop + 833, .Columns.Count)).EntireRow.Copy _
Destination:=wbNew.Sheets(1).Range("A1")
wbNew.Close SaveChanges:=True, Filename:="Chunk" & lCopy & "Rows" & lLoop & "-" & lLoop + 833
Next lLoop
End With
End Sub
Actual results: Excels
Expected results: CSV files
Something like this?
Sub CSVQuotes()
Dim SrcRange As Range
Dim CurrRow As Range
Dim CurrCell As Range
Dim CurrTextStr As String
Dim ListSeparator As String
Dim FileName As Variant
Dim current As String
FileName = Application.GetSaveAsFilename()
ListSeparator = ";"
Set SrcRange = Sheets("DATI").UsedRange
Open FileName For Output As #1
For Each CurrRow In SrcRange.Rows
CurrTextStr = ""
For Each CurrCell In CurrRow.Cells
current = CurrCell
CurrTextStr = CurrTextStr & """" & current & """" & ListSeparator
Next
While Right(CurrTextStr, 1) = ListSeparator
CurrTextStr = Left(CurrTextStr, Len(CurrTextStr) - 1)
Wend
Print #1, CurrTextStr
Next
Close #1
Assuming:
strPath = path to target folder
autoIncrement = variable to increment every loop (so we can differentiate the files names)
strRow = string representing 1 row in the CSV; concatenate all columns of each Excel row, alternating values with separator (",")
You can output CSV with this inside a loop:
Open strPath & "\file-" & autoIncrement & ".csv" For Output As #fileNumber
Print #fileNumber, strRow
Close #fileNumber
Why the below code doesn't work in excel sheet? This code is covert an excel file to text file based on user selection, the selection can be export full excel sheet or selected range and user also can choose delimiter of the text file. I've tested this code in excel sheet form and it works well however if change the userform to embedded in excel sheet, it doesn't work completely. It does generate text file but all value are blank, any idea ?
Public Sub ExportToTextFile(FName As String, SourceFile As String, _
Sep As String, SelectionOnly As Boolean, _
AppendData As Boolean)
Dim wb As Workbook
Dim ws As Worksheet
Dim WholeLine As String
Dim FNum As Integer
Dim RowNdx As Long
Dim ColNdx As Integer
Dim StartRow As Long
Dim EndRow As Long
Dim StartCol As Integer
Dim EndCol As Integer
Dim CellValue As String
StarRange = StrCol & StrRow
EndRange = EndCols & endrows
Application.ScreenUpdating = False
On Error GoTo EndMacro:
FNum = FreeFile
Set wb = Workbooks.Open(SourceFile)
Set ws = wb.Sheets("Sheet1")
If SelectionOnly = True Then
With ActiveSheet.UsedRange
StartRow = .Cells(1).Row
StartCol = .Cells(1).Column
EndRow = .Cells(.Cells.Count).Row
EndCol = .Cells(.Cells.Count).Column
End With
Else
With ActiveSheet.Range(StarRange & ":" & EndRange)
StartRow = .Cells(1).Row
StartCol = .Cells(1).Column
EndRow = .Cells(.Cells.Count).Row
EndCol = .Cells(.Cells.Count).Column
End With
End If
If AppendData = True Then
Open FName For Append Access Write As #FNum
Else
Open FName For Output Access Write As #FNum
End If
For RowNdx = StartRow To EndRow
WholeLine = ""
For ColNdx = StartCol To EndCol
If Cells(RowNdx, ColNdx).Value = "" Then
CellValue = Chr(34) & Chr(34)
Else
CellValue = Cells(RowNdx, ColNdx).Value
End If
WholeLine = WholeLine & CellValue & Sep
Next ColNdx
WholeLine = Left(WholeLine, Len(WholeLine) - Len(Sep))
Print #FNum, WholeLine
Next RowNdx
EndMacro:
On Error GoTo 0
Application.ScreenUpdating = True
Close #FNum
MsgBox "Completed.", vbInformation
ActiveWorkbook.Close
End Sub
Looking at your code:
Dim StartRow As Long
Dim EndRow As Long
Dim StartCol As Integer
Dim EndCol As Integer
Dim CellValue As String
StarRange = StrCol & StrRow
EndRange = EndCols & endrows
I suspect you have some typos in your variable names. Is it StartRow or StrRow, for example?
Without using a fine-toothed comb to do your debugging for you, I would highly recommend that you always use
Option Explicit
at the start of every module. This tells VBA "don't let me use any variables I did not explicitly declare" - which in practice means (most of the time) "warn me if I misspelled a variable".
I also noticed that you set a variable ws in the line
Set ws = wb.Sheets("Sheet1")
Then proceed not to use it. Portland Runner posted a good suggestion for how to make use of such a variable - although without seeing the rest of your code / form, it's not clear if that does a better job for you. Typically "ActiveSheet" is a bad idea - it is usually a relic from recording a macro, but not the most efficient or portable thing to do.
It looks like you took code from a couple of different places and repurposed it. I recommend that you go through line by line and make sure that every line is needed, and does what you want.
Finally, as part of the debugging process I would put a breakpoint (F9) in the line
WholeLine = ""
then step through to see whether lines are being formed as you think they are (input range is right, formatting is right, and line is written correctly). My suspicion lies with the way you define your input range. Are StartRow, StartCol etc. actually what you want them to be?
Finally (and possible most importantly) in the lines
For ColNdx = StartCol To EndCol
If Cells(RowNdx, ColNdx).Value = "" Then
CellValue = Chr(34) & Chr(34)
Else
CellValue = Cells(RowNdx, ColNdx).Value
End If
WholeLine = WholeLine & CellValue & Sep
Next ColNdx
You refer to Cells - but don't reference the workbook / sheet that these cells belong to. I suspect that VBA is referencing a difference sheet than you intended. Again - if you properly create the ws variable, then these lines should be changed to
For ColNdx = StartCol To EndCol
If ws.Cells(RowNdx, ColNdx).Value = "" Then
CellValue = Chr(34) & Chr(34)
Else
CellValue = ws,Cells(RowNdx, ColNdx).Value
End If
WholeLine = WholeLine & CellValue & Sep
Next ColNdx
and that may well solve your problem.