Related
UPDATED CODE AND ISSUES (5/9/2018 1:53PM Eastern)
I am encountering problems trying to import multiple data text files into a fixed worksheet ("Raw Data") using two different delimiters. I am using Application.GetOpenFilename to allow the user to select multiple text files from a folder. The files contain a header row which is semicolon delimited, then several lines of data which is comma delimited. In a single text file, this format can be repeated several times (this is an inspection log file which records and appends data to the same text file for each inspection run, i.e. header line1, some rows of data, header line 2, more rows of data, header line 3, more rows of data, etc.)
I've tried a few approaches to solve this based on other examples I've found on StackOverflow.com but I can't seem to successfully mesh the solutions together to come up with a solution that imports single or multiple text files with two different delimiters within each file. I cannot change the format or content of the original text files, so I can't search and replace different delimiters to a single delimiter.
Here are the remaining issues I'm running into with the attached VBA code:
When importing more than one text file, a blank line is inserted between the files which breaks the .TextToColumns section. It is also asking to replace existing data when importing the second file selected. Is there a more efficient or better way to import data from multiple text files using both commas and semicolons as delimiters?
Within a fixed path on the local hard drive, each new order number creates a new sub-folder to store .txt data files (i.e. C:\AOI_DATA64\SPC_DataLog\IspnDetails\123456-7). Is there a way the user can be prompted to enter a sub-folder name (123456-7) and the VBA script will automatically import all .txt files from this sub-folder, rather than using Application.GetOpenFilename?
Here is a truncated version of one of the data files I'm trying to import. The actual file does not have spaces between the rows of data. I separated them in this example to clearly show each line in the text file.
[StartIspn];Time=04/19/18 12:43:15;User=yeseniar;MachineID=WINDOWS-TEFJCS1;Side=T;DoubleSided;IsOnline=1;IA_Idx=1;SN_Idx=0;IT=0;SPC_Db=1;SPC_Txt=1;TxtFmt=10;E_Rpt=1;D_Img=1;FeedMode=0;
KC17390053F,VIA5F,M North,A8,85.0,45.0,96.0,23.2,9.9,0.0,0.0,0.0,59.0,0.0,0.0,0.0,
KC17390053F,VIA3F,M North,A8,85.0,45.0,96.0,22.3,22.9,0.0,0.0,0.0,59.0,0.0,0.0,0.0,
KC17390053F,FMI1F,S South,A13,12.3,0.0,1.0,3.5,3.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
KC17390053F,FMI13F,S South,A13,12.3,0.0,1.0,3.5,3.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
[StartIspn];Time=04/19/18 14:28:10;User=yeseniar;MachineID=WINDOWS-TEFJCS1;Side=B;DoubleSided;IsOnline=1;IA_Idx=1;SN_Idx=0;IT=0;SPC_Db=1;SPC_Txt=1;TxtFmt=10;E_Rpt=1;D_Img=1;FeedMode=0;
KC17390066B,VIA5B,M North,A8,70.0,50.0,92.0,-38.8,-3.7,0.0,0.0,0.0,50.0,0.0,0.0,0.0,
KC17390066B,VIA6B,M North,A8,70.0,50.0,93.0,-37.7,-23.6,0.0,0.0,0.0,50.0,0.0,0.0,0.0,
KC17390066B,FMI12B,S South,A13,4140.4,0.0,2.0,3.5,129.6,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
KC17390066B,FMI24B,S South,A13,2128.7,0.0,2.0,3.5,119.1,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
Here is what I have so far for importing multiple text files:
Sub Import_DataFile()
' Add an error handler
On Error GoTo ErrorHandler
' Speed up this sub-routine by turning off screen updating and auto calculating until the end of the sub-routine
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
' Define variable names and types
Dim OpenFileName As Variant
Dim i As Long
Dim n1 As Long
Dim n2 As Long
Dim fn As Integer
Dim RawData As String
Dim rngTarget As Range
Dim rngFileList As Range
Dim TargetRow As Long
Dim FileListRow As Long
Dim dLastRow As Long
Dim destCell As Range
' Select the source folder and point list file(s) to import into worksheet
OpenFileName = Application.GetOpenFilename( _
FileFilter:="AOI Inspection Results Data Files (*.txt), *.txt", _
Title:="Select a data file or files to import", _
MultiSelect:=True)
' Import user selected file(s) to "Raw Data" worksheet
TargetRow = 0
Set destCell = Worksheets("Raw Data").Range("B1")
For n2 = LBound(OpenFileName) To UBound(OpenFileName)
fn = FreeFile
Open OpenFileName(n2) For Input As #fn
Application.StatusBar = "Processing ... " & OpenFileName(n2)
Do While Not EOF(fn)
Line Input #fn, RawData
TargetRow = TargetRow + 1
Worksheets("Raw Data").Range("B" & TargetRow).Formula = RawData
Loop
Next n2
Close #fn
Set rngTarget = Worksheets("Raw Data").Range("B1" & ":" & Worksheets("Raw Data").Range("B1").End(xlDown).Address)
With rngTarget
.TextToColumns Destination:=destCell, DataType:=xlDelimited, _
TextQualifier:=xlNone, ConsecutiveDelimiter:=False, Tab:=False, _
Semicolon:=True, Comma:=True, Space:=False, Other:=False, OtherChar:="|", _
FieldInfo:=Array(1, 1), TrailingMinusNumbers:=True
End With
Else: MsgBox "The selected file is not the correct format for importing data."
Exit Sub
End If
Next
' Create a number list (autofill) in Col A to maintain original import sort order
dLastRow = Worksheets("Raw Data").Cells(Rows.Count, "B").End(xlUp).Row
Worksheets("Raw Data").Range("A1:A" & dLastRow).Font.Color = RGB(200, 200, 200)
Worksheets("Raw Data").Range("A1") = "1"
Worksheets("Raw Data").Range("A2") = "2"
Worksheets("Raw Data").Range("A1:A2").AutoFill Destination:=Worksheets("Raw Data").Range("A1:A" & dLastRow), Type:=xlFillDefault
Worksheets("Raw Data").Range("F1:Q" & dLastRow).NumberFormat = "0.0"
' Auto fit the width of columns for RAW Data
Worksheets("Raw Data").Columns("A:Z").EntireColumn.AutoFit
' Turn screen updating and auto calculating back on since file processing is now complete
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
' Reset to defaults in the event of a processing error during the sub-routine execution
ErrorHandler:
Application.StatusBar = False
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
If Err.Number <> 0 Then
' Display a message to the user including the error code in the event of an error during execution
MsgBox "An error number " & Err.Number & " was encountered!" & vbNewLine & _
"Part or all of this VBA script was not completed.", vbInformation, "Error Message"
End If
End Sub
Many questions... Let me give some hints.
Prompting the user for working directory :
Dim fDlg As FileDialog ' dialog box object
Dim sDir As String ' selected path
Dim iretval As Long ' test
Set fDlg = Application.FileDialog(msoFileDialogFolderPicker)
sDir = conDEFAULTPATH ' init
With fDlg
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = sDir
iretval = .Show
If iretval = -1 Then sDir = .SelectedItems(1)
End With
Set fDlg = Nothing ' drop object
If sDir = vbNullString Then
MsgBox "Invalid directory"
Else
If Right$(Trim$(sDir), 1) <> Application.PathSeparator Then _
sDir = Trim$(sDir) & Application.PathSeparator' append closing backslash to pathname
End If
Collecting files to a buffer
Dim FileBuf(100) as string, FileCnt as long
FileCnt=0
FileBuf(FileCnt)=Dir(sDir & "*.txt")
Do While FileBuf(FileCnt) <> vbnullstring
FileCnt = FileCnt + 1
FileBUf(FileCnt) = Dir
Loop
Reducing number of delimiters: simply use replace
RawData = Replace(RawData, ";", ",")
For the blank line I have no clue, though it might be a result of a blank line in the source file, maybe the EOF. So what if you check the line before copying:
If len(trim(RawData)) > 0 Then
TargetRow = TargetRow + 1
Worksheets("Raw Data").Range("B" & TargetRow) = RawData
End If
Please note that I've removed .Formula. You are working with values.
For setting target range: You should omit .Address. For selecting last cell in a range, you should use .End(xlUp) this way:
Set rngTarget = Worksheets("Raw Data").Range("B1" & ":" & Worksheets("Raw Data").Range("B1").End(xlUp))
I prefer using direct cell references, so - as you exactly know the last row - I would do it this way:
Set rngTarget = Worksheets("Raw Data").Range(Cells(1, 2), Cells(TargetRow, 2))
Good Luck!
How do I move down 1 row for every loop until cell empty in column A?
I need to start on Row 5 copy to another workbook then loop to the next row (Row6) until contents are empty.
Here is my code
Sub Macro3()
'''
Do
''GRAB A ROW
Windows("theFILE2.working.xlsm").Activate
Rows("5:5").Select
Selection.Copy
Workbooks.Open "D:\folder1\folder2\Projects\The FILES\New folder\OVERVIEW TEMPLATE(macro edition)(current).xlsm"
Windows("OVERVIEW TEMPLATE(macro edition)(current).xlsm").Activate
Sheets("LISTS").Select
Rows("4:4").Select
ActiveSheet.Paste
Application.CutCopyMode = False
With Selection.Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
Windows("OVERVIEW TEMPLATE(macro edition)(current).xlsm").Activate
Sheets("PLANT OVERVIEW").Select
''SAVE AS
Dim Path As String
Dim FileName1 As String
Dim FileName2 As String
FileName1 = Range("N1").Value
FileName2 = Range("A1").Value
Path = "D:\folder1\folder2\Projects\The FILES\theFILES\" & FileName1 & "\"
ActiveWorkbook.SaveAs Filename:=Path & FileName2 & ".xlsm", FileFormat:=xlOpenXMLWorkbookMacroEnabled
ActiveWorkbook.Close
Loop
End Sub
Thankyou in advanced!
I see you're new to VBA, and there are some concepts you're picking up pretty quickly. Recording macros in Excel is a great way to find out how you could do something in Excel. However, there are some drawbacks to the way Excel does it also. Here are a few concepts that will help:
Don't use Selection, ActiveCell, ActiveSheet, Select, Activate, etc. unless you absolutely have to. I know that's what the Macro Recorder in Excel does, but if you don't do it exactly right, it can cause errors, especially when you start working with multiple workbooks!
Much better to assign an object, and use that object to do what you want to do. In the code below, I assigned the Workbooks and worksheets to objects and used those to get stuff done. Ranges are also common objects to use.
Related to that, make sure to always fully qualify your objects. For example, you can write code like this: Var1 = Cells(1, 1).Value but it will get the value from cell A1 in the Active Worksheet, not necesarily the worksheet or workbook you intended. Much better to write it this way: Var1 = wksSource.Cells(1, 1).Value I did specify a sheet name "Sheet1" for your source workbook - change it to the actual name of the sheet you're copying from.
I assigned the most common strings to Constants at the top. There's a balance between assigning every string to a constant and using only in-line strings (for example, some might assign the sheet names like "LISTS" to a constant), but if they're only used once and in a prominent place, I don't worry about assigning a constant for it. But especially when the value is used multiple places, a constant makes it easier for when you want to re-use the code for a similar task. I also put a constant in there for the Source Path, although that's not required if the workbook is already open.
I also declared all the variables at the top - some languages and programmers do it differently, but I like to be able to see what's being used at the beginning.
Notice the While specifier on your Do ... Loop. This will only loop while there is a value in the first column of the current row.
Here's how I would write the code for your task:
Sub Macro3()
Dim SourceRow As Long
Dim DestRow As Long
Dim Path As String
Dim FileName1 As String
Dim FileName2 As String
Dim FullFileName As String
Dim wkbSource As Workbook
Dim wksSource As Worksheet
Dim wkbDest As Workbook
Dim wksDest As Worksheet
Dim wksDest2 As Worksheet
Const scWkbSourcePath As String = "D:\folder1\folder2\Projects\" ' For example
Const scWkbSourceName As String = "theFILE2.working.xlsm"
Const scWkbDest1Path As String = "D:\folder1\folder2\Projects\The_FILES\New_folder\"
Const scWkbDest1Name As String = "OVERVIEW TEMPLATE_macro edition_current_.xlsm"
Const scWkbDest2Path As String = "D:\folder1\folder2\Projects\The_FILES\theFILES\"
Set wkbSource = Workbooks(scWkbSourceName)
Set wksSource = wkbSource.Sheets("Sheet1") ' Replace Sheet1 with the sheet name
SourceRow = 5
DestRow = 4
Do While wksSource.Cells(SourceRow, 1).Value <> ""
' Open the template workbook
Set wkbDest = Workbooks.Open(scWkbSourcePath & scWkbDest1Name)
Set wksDest = wkbDest.Sheets("LISTS")
''COPY A ROW
wksSource.Rows(SourceRow).Copy Destination:=wksDest.Rows(DestRow)
Application.CutCopyMode = False
With wksDest.Rows(DestRow).Interior
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
.Color = 65535
.TintAndShade = 0
.PatternTintAndShade = 0
End With
wkbDest.Activate
Set wksDest2 = wkbDest.Sheets("PLANT OVERVIEW")
''SAVE AS
FileName1 = Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace(Replace( _
Replace(wksDest2.Range("N1").Value _
, ".", "_") _
, "/", "_") _
, "\", "_") _
, "?", "_") _
, "|", "_") _
, "<", "_") _
, ">", "_") _
, ":", "_") _
, "*", "_") _
, """", "_")
FileName2 = wksDest2.Range("A1").Value
Path = scWkbDest2Path & FileName1 & "\"
If Len(Dir(Path, vbDirectory)) = 0 Then
MkDir Path
End If
FullFileName = Path & FileName2 & ".xlsx"
wkbDest.SaveAs Filename:=FullFileName, FileFormat:=xlOpenXMLWorkbook
wkbDest.Close
' Best practice to set objects to Nothing before re-using an object variable
Set wksDest = Nothing
Set wksDest2 = Nothing
Set wkbDest = Nothing
' Move down 1 row for source sheet
SourceRow = SourceRow + 1
Loop
End Sub
Edit
Some notes and things I learned regarding Folder and File name characters:
Although parentheses can be used in filenames, I wasn't able to get your original filename to save - but removing the parentheses solved the problem.
Since you're creating file and folder names from (potentially dirty) data, you should clean up (remove or replace with _) the characters that can't be used in those names: \ / | ? < > : * "
I found this on a Microsoft page for Naming Files, Paths, and Namespaces:
Do not end a file or directory name with a space or a period.
Although it is allowed inside a file name, a full stop (.) cannot be the last char of a folder name, which is generally where you find it in a text string. Besides, it can be confusing and occasionally cause problems within a file name, so I'd recommend replacing them all.
The Trim() function can be used to remove spaces at the end of a folder name. Be aware that within the string, it also changes multiple spaces in a row to a single space.
Especially since you're creating folders from data, you need to make sure the folder exists before saving a file to it. MkDir is the command for this.
If your template workbook isn't open when you start, you may need to specify the path as well in the Open() statement.
I am trying to write a VBA Script which converts the excel file to XML. I am fetching the file name using Application.GetSaveAsFilename() function. But this function opens up the "Save As" dialog box. I want to suppress the dialog such that the user is not prompted to manually click save each time the code is run. Instead, the XML should be silently generated at the location hard-coded.
Code:
Sub BasicRTE()
Dim FileName As Variant
Dim Sep As String
Dim Ws As Worksheet
Dim autoSetFileName As String
Dim folderName As String
Dim location As Integer
ChDrive (Left(ThisWorkbook.Path, 1))
ChDir ThisWorkbook.Path
ChDir ".."
ChDir "InputFiles"
Application.SendKeys ("{ENTER}")
FileName = Application.GetSaveAsFilename( _
InitialFileName:=ThisWorkbook.Worksheets(1).Name, _
FileFilter:="Xml Files (*.xml),*.xml")
location = InStrRev(FileName, "\", , vbTextCompare)
folderName = Mid(FileName, 1, location - 1)
For Each Ws In ThisWorkbook.Worksheets
If InStr(1, Ws.Name, "#", vbTextCompare) <> 1 Then
ExportToMyXMLFile FName:=CStr(folderName & "\" & Ws.Name & ".xml"), Sep:=CStr(Sep), _
AppendData:=False, Ws:=Ws
End If
Next
End Sub
It appears that the only thing you are using Application.GetSaveAsFilename for is to get the path to the InputFiles path with respect to the location of ThisWorkbook into folderName. The operating system already provides that! The following changes should work (but I have not tested them myself):
' fileName = ... ' don't need this
' location = ... ' or this
folderName = ThisWorkbook.Path & "\..\InputFiles" ' e.g., C:\Users\Foo\Documents\..\InputFiles
Alternatively, if you want a cleaner string,
Dim location as Long ' Never use Integer unless you are calling Win32 or something else esoteric
' Don't need any of this unless later code relies on the current directory
' (which it shouldn't, for robustness).
'ChDrive (Left(ThisWorkbook.Path, 1))
'ChDir ThisWorkbook.Path
'ChDir ".."
'ChDir "InputFiles"
'Application.SendKeys ("{ENTER}")
'FileName = Application.GetSaveAsFilename( _
' InitialFileName:=ThisWorkbook.Worksheets(1).Name, _
' FileFilter:="Xml Files (*.xml),*.xml")
folderName = ThisWorkbook.Path
location = InStrRev(folderName, "\", , vbTextCompare)
folderName = Mid(folderName, 1, location) & "InputFiles"
For Each ws ...
The InStrRev+Mid drops the last path component, just like .., and then the & "InputFiles" puts InputFiles on the end.
One caution: ThisWorkbook.Path is an empty string for a new, unsaved workbook. Make sure your workbook is saved to disk before using the above.
Edit another caution: you are using ws.Name directly in making filenames. However, sheet names can include text that filenames cannot. I can name a sheet CON or <foo>, but neither of those is valid in a filename. Here's one example of sanitizing filenames (a quick Google result — not tested). However, even that example does not appear to check for reserved names.
Reserved names: CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9 per MS).
I have a xlsm that amonst others runs through all .xslx files in a directory, runs a sub, saves them. (Thank you Tabias)
inside this sub I am now trying to add something that would add the last column from a third file.
My first problem here is how to define the sourcefile. We need to take data from the exact file, with a similar name. So MC.xslx ahs to copy from MC12february.xlsx and KA.xlsx has to import from KAwhateverdate.xlsx
Set wbA = Workbooks.Open("C:\files" & "\" & ActiveWorkbook.Name & "*.xlsx")
unfortunately, active.workbook.name includes the extention, so OR you guys can tell me a solution OR i have to save the files date+name first and change it into wbA = Workbooks.Open("C:\files" & "\*" & ActiveWorkbook.Name) right?
The same goes for the sheet. Those wil, depending on the file, be called MC, KA,KC,...
Next since i only want to copy the last column of the file into the last column of the other file I'm quite confused. I found this code and thought it was the most understandable.
Sub import()
Dim Range_to_Copy As Range
Dim Range_Destination As Range
Dim Sheet_Data As Worksheet 'sheet from where we pull the data
Dim Sheet_Destination As Worksheet ' destination
Dim workbook_data As Workbook
Dim workbook_destination As Workbook
Set workbook_data = "N:\blah\deposit" & "\*" & ActiveWorkbook.Name
Set workbook_detination = ActiveWorkbook
Set Sheet_Data = ThisWorkbook.Sheets("Sheet1") 'help, how do i do this?
Set Sheet_Destination = ThisWorkbook.Sheets("Sheet1") ' and this?
Set Range_to_Copy = sht.UsedRange.Rows(sht.UsedRange.Rows.Count).Row
Set Range_Destination = sht.UsedRange.Rows(sht.UsedRange.Rows.Count).Row
Range_to_Copy.Copy Range_Destination 'this copies from range A to B (basically A.copy B), but i changed variable names to make it easier...
'you can simplify without variables like this:
'Sheets("Sheet1").Range("D1").Copy Sheets("Summary).Range("A1") <===== does the same as the above coding
None of the more simpler solutions seemed fit either. example
As you see I'm completely stuck at how to define the last column and the name of the sheet. This code is to uncomplete for me to check by doing. Can someone put me on the right path? thank you.
As a supplement, I'd suggest creating a simeple, re-usable file open functions where you can provide a filename as a String that you'd like to search for. The function will loop through a directory (as Batman suggested) and, optionally, pull the most recent version (using date modified) of that file. Below is a set of functions that I use frequently. There is a subfolder parameter `subF' that will allow you to search within subfolder(s) relative to the current file location.
'FUNCTION opnWB
'--Opens a workbook based on filename parameter
'----WILDCARDS before and after the filename are used to allow for filename flexibility
'----Subfolder is an OPTIONAL PARAMETER used if the location of the file is located in a subfolder
Public Function opnWB(ByVal flNM As String, Optional ByVal subF As String = "") As Workbook
If subF <> "" Then subF = "\" & subF
Dim pthWB As String
pthWB = "\*" & flNM & "*" 'wildcard characters before and after filename
pthWB = filePull(subF, pthWB)
Set opnWB = Workbooks.Open(ActiveWorkbook.path & subF & "\" & pthWB, UpdateLinks:=0)
End Function
'FUNCTION filePull
'--Cycles through folder for files that match the filename parameter (with WILDCARDS)
'--If there is more than one file that matches the filename criteria (with WILDCARDS),
'----the file "Date Modified" attribute is used and the most recent file is "selected"
Private Function filePull(ByVal subF As String, ByVal path As String) As String
Dim lDate, temp As Date
Dim rtrnFl, curFile As String
Filename = Dir(ActiveWorkbook.path & subF & path)
Do While Filename <> ""
curFile = Filename
curFile = ActiveWorkbook.path & subF & "\" & Filename
If lDate = 0 Then
rtrnFl = Filename
lDate = GetModDate(curFile)
Else
temp = GetModDate(curFile)
End If
If temp > lDate Then
rtrnFl = Filename
lDate = temp
End If
Filename = Dir()
Loop
filePull = rtrnFl
End Function
'FUNCTION GetModDate
'--Returns the date a file was last modified
Public Function GetModDate(ByVal filePath As String) As Date
GetModDate = CreateObject("Scripting.FileSystemObject").GetFile(filePath).DateLastModified
End Function
You could tweak this method where the filename would have to start file the String you pass in by simply removing the wildcard character before flNM. To use, you would simply call the opnWB function, passing in "MC" or whatever general file name you'd like to open:
Dim wbTarMC as Workbook
Set wbMC = opnWB("MC", "Source Files") 'this would open up MC.xlsx file within the subfolder "Source Files" (relative to current file location)
Hope this helps.
I have a excel sheet which has data in column A.There are many special characters in the cells.When I save the sheet in .txt format I get inverted commas at the start of each line. I tried both manually and by macro saving the file in .txt format.Why is it so? How to remove them?
I am not able to remove the quotes.
Attaching a pic
I see this question is already answered, but wanted to offer an alternative in case someone else finds this later.
Depending on the required delimiter, it is possible to do this without writing any code. The original question does not give details on the desired output type but here is an alternative:
PRN File Type
The easiest option is to save the file as a "Formatted Text (Space Delimited)" type.
The VBA code line would look similar to this:
ActiveWorkbook.SaveAs FileName:=myFileName, FileFormat:=xlTextPrinter, CreateBackup:=False
In Excel 2007, this will annoyingly put a .prn file extension on the end of the filename, but it can be changed to .txt by renaming manually.
In Excel 2010, you can specify any file extension you want in the Save As dialog.
One important thing to note: the number of delimiters used in the text file is related to the width of the Excel column.
Observe:
Becomes:
This code does what you want.
LOGIC
Save the File as a TAB delimited File in the user temp directory
Read the text file in 1 go
Replace "" with blanks and write to the new file at the same time.
CODE
Private Declare Function GetTempPath Lib "kernel32" Alias "GetTempPathA" _
(ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long
Private Const MAX_PATH As Long = 260
'~~> Change this where and how you want to save the file
Const FlName = "C:\Users\Siddharth Rout\Desktop\MyWorkbook.txt"
Sub Sample()
Dim tmpFile As String
Dim MyData As String, strData() As String
Dim entireline As String
Dim filesize As Integer
'~~> Create a Temp File
tmpFile = TempPath & Format(Now, "ddmmyyyyhhmmss") & ".txt"
ActiveWorkbook.SaveAs Filename:=tmpFile _
, FileFormat:=xlText, CreateBackup:=False
'~~> Read the entire file in 1 Go!
Open tmpFile For Binary As #1
MyData = Space$(LOF(1))
Get #1, , MyData
Close #1
strData() = Split(MyData, vbCrLf)
'~~> Get a free file handle
filesize = FreeFile()
'~~> Open your file
Open FlName For Output As #filesize
For i = LBound(strData) To UBound(strData)
entireline = Replace(strData(i), """", "")
'~~> Export Text
Print #filesize, entireline
Next i
Close #filesize
MsgBox "Done"
End Sub
Function TempPath() As String
TempPath = String$(MAX_PATH, Chr$(0))
GetTempPath MAX_PATH, TempPath
TempPath = Replace(TempPath, Chr$(0), "")
End Function
SNAPSHOTS
Actual Workbook
After Saving
Ummm, How about this.
Copy your cells.
Open Notepad.
Paste.
Look no quotes, no inverted commas, and retains special characters, which is what the OP asked for. Its also delineated by carriage returns, same as the attached pict which the OP didn't mention as a bad thing (or a good thing).
Not really sure why a simple answer, that delivers the desired results, gets me a negative mark.
I just spent the better part of an afternoon on this
There are two common ways of writing to a file, the first being a direct file access "write" statement. This adds the quotes.
The second is the "ActiveWorkbook.SaveAs" or "ActiveWorksheet.SaveAs" which both have the really bad side effect of changing the filename of the active workbook.
The solution here is a hybrid of a few solutions I found online. It basically does this:
1) Copy selected cells to a new worksheet
2) Iterate through each cell one at a time and "print" it to the open file
3) Delete the temporary worksheet.
The function works on the selected cells and takes in a string for a filename or prompts for a filename.
Function SaveFile(myFolder As String) As String
tempSheetName = "fileWrite_temp"
SaveFile = "False"
Dim FilePath As String
Dim CellData As String
Dim LastCol As Long
Dim LastRow As Long
Set myRange = Selection
'myRange.Select
Selection.Copy
'Ask user for folder to save text file to.
If myFolder = "prompt" Then
myFolder = Application.GetSaveAsFilename(fileFilter:="XML Files (*.xml), *.xml, All Files (*), *")
End If
If myFolder = "False" Then
End
End If
Open myFolder For Output As #2
'This temporarily adds a sheet named "Test."
Sheets.Add.Name = tempSheetName
Sheets(tempSheetName).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
LastCol = ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Column
LastRow = ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Row
For i = 1 To LastRow
For j = 1 To LastCol
CellData = CellData + Trim(ActiveCell(i, j).Value) + " "
Next j
Print #2, CellData; " "
CellData = ""
Next i
Close #2
'Remove temporary sheet.
Application.ScreenUpdating = False
Application.DisplayAlerts = False
ActiveWindow.SelectedSheets.Delete
Application.DisplayAlerts = True
Application.ScreenUpdating = True
'Indicate save action.
MsgBox "Text File Saved to: " & vbNewLine & myFolder
SaveFile = myFolder
End Function
The answer from this question provided the answer to this question much more simply.
Write is a special statement designed to generate machine-readable
files that are later consumed with Input.
Use Print to avoid any fiddling with data.
Thank you user GSerg
I have the same problem: I have to make a specific .txt file for bank payments out of an excel file. The .txt file must not be delimeted by any character, because the standard requires a certain number of commas after each mandatory field.
The easiest way of doing it is to copy the contect of the excel file and paste it in notepad.
I was using Write #1 "Print my Line" instead I tried Print #1, "Print my Line" and it give me all the data without default Quote(")
Dim strFile_Path As String
strFile_Path = ThisWorkbook.Path & "\" & "XXXX" & VBA.Format(VBA.Now, "dd-MMM-yyyy hh-mm") & ".txt"
Open strFile_Path For Output As #1
Dim selectedFeature As String
For counter = 7 To maxNumberOfColumn
selectedFeature = "X"
Print #1, selectedFeature
'Write #1, selectedFeature
Next counter
Close #1
PRN solution works only for simple data in the cells, for me it cuts only first 6 signs from 200 characters cell.
These are the main file formats in Excel 2007-2016,
Note: In Excel for the Mac the values are +1
51 = xlOpenXMLWorkbook (without macro's in 2007-2016, xlsx)
52 = xlOpenXMLWorkbookMacroEnabled (with or without macro's in 2007-2016, xlsm)
50 = xlExcel12 (Excel Binary Workbook in 2007-2016 with or without macro's, xlsb)
56 = xlExcel8 (97-2003 format in Excel 2007-2016, xls)
From XlFileFormat FileFormat Property
Keep in mind others FileFormatNumbers for SaveAs method:
FileExtStr = ".csv": FileFormatNum = 6
FileExtStr = ".txt": FileFormatNum = -4158
FileExtStr = ".prn": FileFormatNum = 36