Correct Excel Macro to Save A Copy Excel File as TXT or CSV - vba

So I have this home-made Excel Macro Template.
The task of the macro code that I inserted in my xlsm file is to Save a copy in the same folder with a different format. That format is .txt (see image below)
The expected result of the macro (after saving) should be the same with the excel file (visually) but this time it is in a .txt format.
Unfortunately, that didn't happened. It generates a different txt file and it contains unreadable alpha numeric characters, here's an example of the generated txt file.
¬TËNÃ0 ¼#ñ ‘¯(vဠjÚ # °µ· ©c[^SÚ¿g“–
P ö '±wfvìq 8o\1ÃD6øJœËž(Ðë`¬ŸTâõå¾¼ eð \ðX‰ ’ NOú/‹ˆTpµ§JÔ9Çk¥H×Ø É ÑóÌ8¤ 2 ¦‰Š §0AuÑë]* |FŸËÜbˆAÿ Çðîrq7çßK%#ëEq³\×RU btVCf¡jæ l¨ã±Õ(g#xJá
u j#XBG{Ð~J.Wr%WvŒTÛHgÜÓ †vf»ÜUÝ#ûœ¬Áâ R~€†›Rs§>BšŽB˜ÊÝ «žq®ÑIª ³l#§pçaä ý ë¿ î`ê*IuÃù ( ³´Ü ýÞð JŠ Át` “m'Ýû ™ ªîy¸„ f !å…C:r·KÐ}Ì5$4Ï9q Ž.à;ö. ¼] H ¼„ÿwá+mu S¶¸ŽÃ¦Ã¶fäÔ l;¶×‚A³ [u×Ðà ÿÿ PK ! µU0#ô L _rels/.rels ¢ (
Here's my macro code:
Sub SaveMe()
Dim FName As Range
Dim firstDate As String
Dim firstTime As String
Dim answer As Integer
firstDate = Format(Date, "mmddyyyy")
firstTime = Format(Now, "hhmmssAM/PM")
Set FName = Range("H5")
ActiveWorkbook.SaveCopyAs FileName:=ActiveWorkbook.Path & "\" & "QB JE " & FName & " " & firstDate & " " & firstTime & ".txt", FileFormat:=xlText, CreateBackup:=False
End Sub
I was wondering if anyone could take a look at my code and help to point out whats wrong.

It looks like you want the SaveAs Not the SaveCopyAs.
Fileformat xlText or xlTextMSDOS
You can two step the process. Save a copy, then open it, and save it as a text file.
ActiveWorkbook.SaveCopyAs FileName:=ActiveWorkbook.Path & "\" & "QB JE " & FName & " " & firstDate & " " & firstTime & ".xlsx"
Workbooks.Open (ActiveWorkbook.Path & "\" & "QB JE " & FName & " " & firstDate & " " & firstTime & ".xlsx")
ActiveWorkbook.SaveAs FileName:=ActiveWorkbook.Path & "\" & "QB JE " & FName & " " & firstDate & " " & firstTime & ".txt", FileFormat:=xlText, CreateBackup:=False
https://msdn.microsoft.com/en-us/library/office/ff841185.aspx
https://msdn.microsoft.com/en-us/library/office/ff198017.aspx

See from my post here. Excel VBA Export To Text File with Fixed Column Width + Specified Row and Columns Only + Transpose
Loop all rows and all cells. Send each value to a padspace function. Build the string from for each cells value with spaces padded after the cell value.
You will have to add a reference to you workbook. In the VBA IDE go to the tools pull down menu and select references. Then scroll down and select "Microsoft Scripting Runtime". Then hit OK.
Adjust the pad space function call argument to a number that fits the data that you have in your spreadsheet. So you will change the 20 in the line with the padspace call. PadSpace(20, len(cellValue))
This will do all rows and columns.
Public Sub MyMacro()
Dim lRow As Long
Dim lCol As Long
Dim strRow As String
Dim ws As Excel.Worksheet
Dim ts As TextStream
Dim fs As FileSystemObject
'Create the text file to write to
Set fs = New FileSystemObject
Set ts = fs.CreateTextFile("C:\Temp\test.txt", True, False)
Set ws = Application.ActiveSheet
'Loop through all the rows.
lRow = 1
Do While lRow <= ws.UsedRange.Rows.count
'Clear the string we are building
strRow = ""
'Loop through all the columns for the current row.
lCol = 1
Do While lCol <= ws.UsedRange.Columns.count
'Build a string to write out.
strRow = strRow & ws.Cells(lRow, lCol) & PadSpace(20, Len(ws.Cells(lRow, lCol)))
lCol = lCol + 1
Loop
'Write the line to the text file
ts.WriteLine strRow
lRow = lRow + 1
ws.Range("A" & lRow).Activate
Loop
ts.Close: Set ts = Nothing
Set fs = Nothing
End Sub
'This function will take the max number of spaces you want and the length of the string in the cell and return you the string of spaces to pad.
Public Function PadSpace(nMaxSpace As Integer, nNumSpace As Integer) As String
If nMaxSpace < nNumSpace Then
PadSpace = ""
Else
PadSpace = Space(nMaxSpace - nNumSpace)
End If
End Function

Related

Save as CSV saves file with formulas as #NAME?

I have a module function in this report that concatenates certain cells:
Function AnalysisResults(Specs As Range, Results As Range)
AnalysisResults = Join(Specs) & ";" & Replace(Join(Results), ",", ".")
End Function
Private Function Join(Range As Range, Optional ByRef Delimeter As String = " ")
Dim Str As String
For Each cell In Range
If Str <> "" Then Str = Str & Delimeter
Str = Str & cell.Value
Next
Join = Str
End Function
Then i have a command button that save my file as CSV. It works, but the where the function cells are the value saved is #NAME?.
If I Save As manually as CSV comma delimited, it saves correctly and the formula values appears.
Here is the code of the CommandButton:
Dim myValue As Variant
myValue = InputBox("Specifica numele WBT-ului de descarcare:", "Save WBT with the following name", 1)
Range("L2").Value = myValue
Dim CopyToCSV()
Dim MyPath As String
Dim MyFileName As String
Sheets("Manual Discharge WBT").EnableCalculation = True
MyPath = "\\FILES\Transfer\~~TTS Import (do not delete)~~\Import Files\"
MyFileName = Range("L2") & " Discharge " & Format(CStr(Now), " dd_mm_yyyy_hh_mm")
If Not Right(MyPath, 1) = "\" Then MyPath = MyPath & "\"
If Not Right(MyFileName, 4) = ".csv" Then MyFileName = MyFileName & ".csv"
Sheets("Manual Discharge WBT").Copy
With ActiveWorkbook
.SaveAs Filename:= _
MyPath & MyFileName, _
FileFormat:=xlCSVWindows, _
CreateBackup:=False
.Close False
MsgBox "Fisierul tau s-a salvat ca: " & MyFileName
End With
The solution is, you will have to save your AnalysisResults and Join functions as an add-in file .xlam and add to excel at Developer->Add-ins. Doing it this way the above code worked for me when saving to CSV without #NAME?
What was happening here was that when excel is trying to save the file to CSV, it doesn't know what the AnalysisResults function is.

Removing White Space

I need help creating separate text files from each row in an excel spread sheet called "worksheet". I want the text files to be named with content of Column A + “Result”+ Column H (Which should be hidden in the .txt file, with columns B-G being the content, I have done the coding. Please find the followings. But I have received whitespace in the .txt output file. Please find the screenshots. I am unable to TRIM this white space.
How would I proceed further to solve the problem?
Thanks in Advance.
VBA Code:
Sub WriteTotxt()
Const forReading = 1, forAppending = 3, fsoForWriting = 2
Dim fs, objTextStream, sText As String
Dim lLastRow As Long, lRowLoop As Long, lLastCol As Long, lColLoop As Long
lLastRow = Cells(Rows.Count, 1).End(xlUp).Row
For lRowLoop = 1 To lLastRow
Set fs = CreateObject("Scripting.FileSystemObject")
Set objTextStream = fs.opentextfile("D:\EXCEL_TXT_TEST\New folder\" & Cells(lRowLoop, 8) & "-" & "RESULT" & "-" & Cells(lRowLoop, 1) & ".txt", fsoForWriting, True)
sText = ""
sText1 = ""
For lColLoop = 1 To 7
If lColLoop <> 7 Then
sText = sText & "<" & Cells(lColLoop) & ">" & "," & Chr(0)
sText1 = sText1 & Cells(lRowLoop, lColLoop) & "," & Chr(0)
Else
sText = sText & "<" & Cells(lColLoop) & ">" & Chr(0)
sText1 = sText1 & Cells(lRowLoop, lColLoop) & Chr(0)
End If
Next lColLoop
objTextStream.writeline (Left(sText, Len(Trim(sText)) - 1))
objTextStream.writeline (Left(sText1, Len(Trim(sText1)) - 1))
objTextStream.Close
Set objTextStream = Nothing
Set fs = Nothing
Next lRowLoop
End Sub
You can remove all the blank lines from a string like this
mystr = replace(mystr, vblf & vbcr, "")
This will remove empty lines, not lines that contain spaces or other characters you can't see though..
I can help with your code as well, but have you tried a simple approach first?
Why don't you just file --> save as .csv, and replace your header? Your data output will be VERY similar, save for the " " space preceding your listed entries. Lazy but easy.
adapt this to your module, and you can erase like everything you have ...
ActiveWorkbook.SaveAs Filename:= _
"c:\MyFile.csv", FileFormat:=xlCSV _
, CreateBackup:=False
Then, just read your data back in, and string operations will be easy.

Read a value from a cell without opening the Workbook [duplicate]

I found this bit of code and thought it might be good to use if I just need to pull one value from a closed sheet.
strInfoCell = "'" & strPath & "[" & strFile & "]Sheet1'!R3C3"
myvalue = ExecuteExcel4Macro(strInfoCell)
When I run this code I get a value for strinfocell of
'C:\Users\my.name\Desktop[QOS DGL stuff.xlsx]Sheet1'!R3C3
But when I run the code a dialogue pops up, showing desktop files with "QOS DGL suff" showing.
What's causing this, why is it not just pulling back the data as expected?
I know the path and file name are right, because if I copy them from the debug output and paste them in to start>>run then the correct sheet opens.
I know that Sheet1 (named: ACL), does have a value in cells(3,3)
It depends on how you use it. The open file dialog box is being showed to you because the "strPath" doesn't have a "" in the end ;)
Try this code.
Option Explicit
Sub Sample()
Dim wbPath As String, wbName As String
Dim wsName As String, cellRef As String
Dim Ret As String
'wbPath = "C:\Documents and Settings\Siddharth Rout\Desktop\"
wbPath = "C:\Users\my.name\Desktop\"
wbName = "QOS DGL stuff.xls"
wsName = "ACL"
cellRef = "C3"
Ret = "'" & wbPath & "[" & wbName & "]" & _
wsName & "'!" & Range(cellRef).Address(True, True, -4150)
MsgBox ExecuteExcel4Macro(Ret)
End Sub
Similar application, but no hard coded paths as in the examples above. This function copies the value from another closed workbook, similar to the =INDIRECT() function, but not as sophisticated. This only returns the value...not a reference..so it cannot be used with further functions which require references (i.e.: VLOOKUP()). Paste this code into a new VBA module:
'Requires filename, sheetname as first argument and cell reference as second argument
'Usage: type in an excel cell -> =getvalue(A1,B1)
'Example of A1 -> C:\TEMP\[FILE1.XLS]SHEET1'
'Example of B1 -> B3
'This will fetch contents of cell (B3) located in (sheet1) of (c:\temp\file1.xls)
'Create a module and paste the code into the module (e.g. Module1, Module2)
Public xlapp As Object
Public Function getvalue(ByVal filename As String, ref As String) As Variant
' Retrieves a value from a closed workbook
Dim arg As String
Dim path As String
Dim file As String
filename = Trim(filename)
path = Mid(filename, 1, InStrRev(filename, "\"))
file = Mid(filename, InStr(1, filename, "[") + 1, InStr(1, filename, "]") - InStr(1, filename, "[") - 1)
If Dir(path & file) = "" Then
getvalue = "File Not Found"
Exit Function
End If
If xlapp Is Nothing Then
'Object must be created only once and not at each function call
Set xlapp = CreateObject("Excel.application")
End If
' Create the argument
arg = "'" & filename & "'!" & Range(ref).Range("A1").Address(, , xlR1C1)
'Execute an XLM macro
getvalue = xlapp.ExecuteExcel4Macro(arg)
End Function
Code above
strInfoCell = "'" & strPath & "[" & strFile & "]Sheet1'!R3C3"
myvalue = ExecuteExcel4Macro(strInfoCell)
Should read
strInfoCell = "'" & strPath & "[" & strFile & "]" & "Sheet1'!R3C3"
myvalue = ExecuteExcel4Macro(strInfoCell)
It is missing " & "
No need for a function
Cheers
Neil
Data = "'" & GetDirectory & "[" & GetFileName & "]" & Sheet & "'!" & Range(Address).Range("A1").Address(, , xlR1C1)
Address = "$C$3"
GetDirectory = "C:\Users\my.name\Desktop\"
GetFileName = "QOS DGL stuff.xlsx"
Sheet = "ACL"

Error when getting data from closed excel workbooks with a dynamic range

I’m getting an error 1004 with my code which takes data from closed workbooks in a list. The code functions as it should and retrieves the values without an issue, however it still brings up the error message. I’m probably missing something very obvious so I’d appreciate any help anyone can provide. Below is my code:
Sub ExecMacro4Excel()
Dim path As String
Dim workbookName As String
Dim worksheetName As String
Dim cell As String
Dim returnedValue As String
Dim lRow, x As Integer
Dim wbName As String
On Error GoTo PROC_ERR
lRow = Sheets("Raw Data").Range("C" & Rows.Count).End(xlUp).Row
path = Sheets("Front").Range("B4").Value
worksheetName = "Template"
cell = "J2"
x = 1
Do
x = x + 1
workbookName = Sheets("Raw Data").Range("C" & x).Value
returnedValue = "'" & path & "[" & workbookName & "]" & _
worksheetName & "'!" & Range(cell).Address(True, True, -4150)
Sheets("Raw Data").Range("I" & x) = ExecuteExcel4Macro(returnedValue)
Loop Until x = lRow
PROC_ERR:
MsgBox "Error: (" & Err.Number & ") " & Err.Description, vbCritical
End Sub
To further clarify, below shows the location where the data is the 1row variable is located and where the data will be put:
http://i.imgur.com/1UcuTd8.png
In addition here is the spreadsheet where the original data is kept and is the same for all of the files:
http://i.imgur.com/j40FD3z.png
And finally, this is the error box reads: "error 1004: A formula in this worksheet contains one or more invalid references. Verify your formulas contain a valid path, workbook, range name and cell reference".
Not sure why you want to use xlR1C1 for the range address, you might have just missed the = at the beginning of returnedValue. You can do it more simpler (assuming path will not change):
Sub ExecMacro4Excel()
Const worksheetName = "Template"
Const cell = "$J$2"
Dim path As String
Dim workbookName As String
'Dim worksheetName As String
'Dim cell As String
Dim returnedValue As String
Dim lRow, x As Integer
Dim wbName As String
On Error GoTo PROC_ERR
path = Sheets("Front").Range("B4").Value
If Right(path, 1) <> Application.PathSeparator Then path = path & Application.PathSeparator
lRow = Sheets("Raw Data").Range("C" & Rows.Count).End(xlUp).Row
For x = 2 To lRow
workbookName = Sheets("Raw Data").Range("C" & x).Value
returnedValue = "='" & path & "[" & workbookName & "]" & _
worksheetName & "'!" & Range(cell).Address
Sheets("Raw Data").Range("I" & x).Formula = returnedValue
Next
PROC_ERR:
MsgBox "Error: (" & Err.Number & ") " & Err.Description, vbCritical
End Sub
I managed to solve this issue myself. The problem was that the list of file names was copied from another list and pasted in. The way I coded it the area selected wasn't done by finding the last row and copying only that section, instead it copied a finite number of cells, which included the data AND blank cells. So as the files were accessed the code worked fine, but when it came to the one following which had a blank cell it caused an error to occur.

How to create a separate CSV file from VBA?

I need to output some results as a .csv file, that gets parsed later on by another process. In order to produce these results, I have a huge workbook containing all the macros and functions that I need.
Is it possible to "create" a separate .csv file from VBA?
Is it possible to use VBA features to write into it instead of just writing in a "raw textual" approach?
Is something like this what you want?
Option Explicit
Sub WriteFile()
Dim ColNum As Integer
Dim Line As String
Dim LineValues() As Variant
Dim OutputFileNum As Integer
Dim PathName As String
Dim RowNum As Integer
Dim SheetValues() As Variant
PathName = Application.ActiveWorkbook.Path
OutputFileNum = FreeFile
Open PathName & "\Test.csv" For Output Lock Write As #OutputFileNum
Print #OutputFileNum, "Field1" & "," & "Field2"
SheetValues = Sheets("Sheet1").Range("A1:H9").Value
ReDim LineValues(1 To 8)
For RowNum = 1 To 9
For ColNum = 1 To 8
LineValues(ColNum) = SheetValues(RowNum, ColNum)
Next
Line = Join(LineValues, ",")
Print #OutputFileNum, Line
Next
Close OutputFileNum
End Sub
Don't forget you will need to put quotes around any field containing a comma.
Tony's answer generally works but doesn't handle the case where your text contains commas or quotes. You may prefer to use Workbook.SaveAs method.
Here is an example if you want to save the content of the Sheet1 as a separated csv file.
Sub create_csv()
Dim FileName As String
Dim PathName As String
Dim ws As Worksheet
Set ws = ActiveWorkbook.Sheets("Sheet1")
FileName = "filename.csv"
PathName = Application.ActiveWorkbook.Path
ws.Copy
ActiveWorkbook.SaveAs FileName:=PathName & "\" & FileName, _
FileFormat:=xlCSV, CreateBackup:=False
End Sub
Imagine that your Sheet1 contains :
lorem ipsum
lore,m ips"um"
The output csv file will be :
lorem,ipsum
"lore,m","ips""um"""
You may write a macro like to save the current workbook (opened excel file) in CSV from VBA:
ActiveWorkbook.SaveAs Filename:="C:\Book1.csv", _
FileFormat:=xlCSVMSDOS, CreateBackup:=False
For those writing the CSV manually, you need to handle commas, double quotes and new lines.
e.g.
Sub WriteToCsv(Items() as String)
OutFile = FreeFile
Open "Outfile.csv" For Output As #OutFile
Print #OutFile, "Header"
For Each Item In Items
If InStr(1, Item, Chr(34)) > 0 Then Item = Chr(34) & Replace(Item, Chr(34), Chr(34) & Chr(34)) & Chr(34)
If InStr(1, Item, ",") > 0 And Left(Item, 1) <> Chr(34) Then Item = Chr(34) & Item & Chr(34)
If InStr(1, Item, vbLf) > 0 And Left(Item, 1) <> Chr(34) Then Item = Chr(34) & Item & Chr(34)
Print #OutFile, Item
Next
Close OutFile
End Sub
Took your code as a basis (THANKS!!!) but had to modify it to make it work.
It didn't handle multiple rows, all cells were put after each other.
2 loops: one to go through the rows and one to go through the cells of each row.
Each time the row loop starts the temporary string is emptied. Before starting a new row, the temp string is added to the Outfile.
Sub ToCsv()
Dim rng As Range
Dim row As Range
Dim cell As Range
Dim ItemNew As String
Set rng = Range("A1:E2") 'Adjust the range accordingly
OutFile = FreeFile
Open "Outfile.csv" For Output As #OutFile
'Print #OutFile, "Header"
For Each row In rng.Rows
ItemNew = ""
For Each Item In row.Cells
If InStr(1, Item, Chr(34)) > 0 Then Item = Chr(34) & Replace(Item, Chr(34), Chr(34) & Chr(34)) & Chr(34)
If InStr(1, Item, ",") > 0 And Left(Item, 1) <> Chr(34) Then Item = Chr(34) & Item & Chr(34)
If InStr(1, Item, vbLf) > 0 And Left(Item, 1) <> Chr(34) Then Item = Chr(34) & Item & Chr(34)
If ItemNew = "" Then
ItemNew = Item
Else
ItemNew = ItemNew & "," & Item
End If
Next
Print #OutFile, ItemNew
Next
Close OutFile
End Sub