excel macro save sheets as csv with specific delimiter and enclosure - vba

I am a total dummy as for vb and excel, have tried to combine 2 macros that I have found around here, into 1, but obviously did something terribly wrong and now i'm stuck.. First I just used this macro (saved it in as personal.xlsb so as to be able to use it in any workbook)
Sub CSVFile()
Dim SrcRg As Range
Dim CurrRow As Range
Dim CurrCell As Range
Dim CurrTextStr As String
Dim ListSep As String
Dim FName As Variant
FName = Application.GetSaveAsFilename("", "CSV File (*.csv), *.csv")
ListSep = ";"
If Selection.Cells.Count > 1 Then
Set SrcRg = Selection
Else
Set SrcRg = ActiveSheet.UsedRange
End If
Open FName For Output As #1
For Each CurrRow In SrcRg.Rows
CurrTextStr = ìî
For Each CurrCell In CurrRow.Cells
CurrTextStr = CurrTextStr & """" & GetUTF8String(CurrCell.Value) & """" & ListSep
Next
While Right(CurrTextStr, 1) = ListSep
CurrTextStr = Left(CurrTextStr, Len(CurrTextStr) - 1)
Wend
Print #1, CurrTextStr
Next
Close #1
End Sub
That plus the GetUTF8String function code. Now that was working fine. Then I have thought well why not just experiment with my limited (that is a serious understatement) vb understanding, added the following code and changed the CSVFile sub into a function, which I then called from the sub below, with the output file name as a parameter (to be used instead FName = Application.GetSaveAsFilename). I thought yeah, this code saves all sheets automatically, now let's just make sure that the encoding and delimiter/enclosure setting function runs before each sheet is saved. It doesn't seem right but I thought hey why not try..
Public Sub SaveAllSheetsAsCSV()
On Error GoTo Heaven
' each sheet reference
Dim Sheet As Worksheet
' path to output to
Dim OutputPath As String
' name of each csv
Dim OutputFile As String
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.EnableEvents = False
' Save the file in current director
OutputPath = ThisWorkbook.Path
If OutputPath <> "" Then
Application.Calculation = xlCalculationManual
' save for each sheet
For Each Sheet In Sheets
OutputFile = OutputPath & Application.PathSeparator & Sheet.Name & ".csv"
' make a copy to create a new book with this sheet
' otherwise you will always only get the first sheet
Sheet.Copy
' this copy will now become active
CSVFile(OutputFile)
ActiveWorkbook.SaveAs Filename:=OutputFile, FileFormat:=xlCSV, CreateBackup:=False
ActiveWorkbook.Close
Next
Application.Calculation = xlCalculationAutomatic
End If
Finally:
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.EnableEvents = True
Exit Sub
Heaven:
MsgBox "Couldn't save all sheets to CSV." & vbCrLf & _
"Source: " & Err.Source & " " & vbCrLf & _
"Number: " & Err.Number & " " & vbCrLf & _
"Description: " & Err.Description & " " & vbCrLf
GoTo Finally
End Sub
Saved that and with that I have managed to achieve something very different. On opening any workbooks, that macro runs and opens up my sheets from that particular workbook as csv files (without saving them). Now I am like Alice in Wonderland. How come it is running on file open? That is not desirable, so I went back to the macro code and changed it back to just the csvfile sub. Well that didn't help, no idea what I did there, was definitely editing the same macro... So I deleted the macro, the modul, I cannot imagine where the thing now is but it's still running + I get this warning that macros were deactivated. Can't get rid of it! Now lads, I'm sorry for the total lack of professionality from my side, this was just supposed to be a small favor for a client, without wasting loads of time learning vb, coz my boss doesn't like that... I am of course interested in how to achieve the goal of saving the sheets automatically after setting the deimiter and enclosure in them. And at this moment I am very interested in how to get rid of that macro and where it is hiding.. What have I done?! Thank you for your patience!

I think the problem lies with the line
OutputPath = ThisWorkbook.Path
Because you are running this from your personal.xlsb which is stored in your XLSTART folder it has created the CSV files in the same location. When Excel starts it will try and load any files that it finds in that location.
Just locate your XLSTART folder and delete any CSV files you find there.
Try using
OutputPath = ActiveWorkbook.Path
XLSTART folder location, dependent on your system, is probably something like:
C:\Users\YOURNAME\AppData\Roaming\Microsoft\Excel\XLSTART

Related

Convert .txt file to .xlsx & remove unneeded rows & format columns correctly

I've got a folder which contains .txt files (they contain PHI, so I can't upload the .txt file, or an example without PHI, or even any images of it). I need an excel macro, which will allow the user to choose the folder containing the file, and will then insert the .txt file data into a new excel workbook, format the rows and columns appropriately, and finally save the file to the same folder that the source was found in.
So far I've got all of that working except for the formatting of rows and columns. As of now, the .txt data is inserted to a new workbook & worksheet, but I can't seem to figure out how to get rid of rows I don't need, or how to get the columns formatted appropriately.
Again, I can't upload the .txt file (or anything) because the Healthcare organization I work for blocks it - even if I've removed all PHI.
Below is the macro I've created so far:
Private Sub CommandButton2_Click()
On Error GoTo err
'Allow the user to choose the FOLDER where the TEXT file(s) are located
'The resulting EXCEL file will be saved in the same location
Dim FldrPath As String
Dim fldr As FileDialog
Dim fldrChosen As Integer
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.Title = "Select a Folder containing the Text File(s)"
.AllowMultiSelect = False
.InitialFileName = "\\FILELOCATION"
fldrChosen = .Show
If fldrChosen <> -1 Then
MsgBox "You Chose to Cancel"
Else
FldrPath = .SelectedItems(1)
End If
End With
If FldrPath <> "" Then
'Make a new workbook
Dim newWorkbook As Workbook
Set newWorkbook = Workbooks.Add
'Make worksheet1 of new workbook active
newWorkbook.Worksheets(1).Activate
'Completed files are saved in the chosen source file folder
Dim CurrentFile As String: CurrentFile = Dir(FldrPath & "\" & "*.txt")
Dim strLine() As String
Dim LineIndex As Long
Application.ScreenUpdating = False
Application.DisplayAlerts = False
While CurrentFile <> vbNullString
'How many rows to place in Excel ABOVE the data we are inserting
LineIndex = 0
Close #1
Open FldrPath & "\" & CurrentFile For Input As #1
While Not EOF(1)
'Adds number of rows below the inserted row of data
LineIndex = LineIndex + 1
ReDim Preserve strLine(1 To LineIndex)
Line Input #1, strLine(LineIndex)
Wend
Close #1
With ActiveSheet.Range("A1").Resize(LineIndex, 1)
.Value = WorksheetFunction.Transpose(strLine)
.TextToColumns Other:=True, OtherChar:="|"
End With
ActiveSheet.UsedRange.EntireColumn.AutoFit
ActiveSheet.Name = Replace(CurrentFile, ".txt", "")
ActiveWorkbook.SaveAs FldrPath & "\" & Replace(CurrentFile, ".txt", ".xls"), xlNormal
ActiveWorkbook.Close
CurrentFile = Dir
Wend
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End If
Done:
Exit Sub
err:
MsgBox "The following ERROR Occurred:" & vbNewLine & err.Description
ActiveWorkbook.Close
End Sub
Any ideas of how I can delete entire lines from being brought into excel?
And how I can format the columns appropriately? So that I'm not getting 3 columns from the .txt file all jammed into 1 column in the resulting excel file?
Thanks
I'd recommend you not to re-invent the wheel. Microsoft provides an excellent add-on to accomplish this task, Power Query.
It lets you to load every file in a folder and process it in bulks.
Here you have a brief introduction of what can do for you.

Taking info from closed workbook that has variable name

I am wondering if there is a way to not have to open a workbook to get the information from it. The issue is I am having the user select the file first because the name changes. So I am using Application.GetOpenFilename. Once they select it, since it doesn't actually open, I am trying to just grab some cells from there and copy them over. I have some other cells using vlookups referencing a workbook in the same way but this seems different or won't work. Here is the code:
Dim Window3 As String
Dim x As String
Dim lNewBracketLocation As Long
Dim shtName As String
' Prompt
strPrompt = "Please select the last 'HC Report' located in" & vbCrLf & _
"'C:\file\file\'" & vbCrLf & _
"before the dates of this Report." & vbCrLf & _
"This will be used to find the Interns that are currently working." & vbCrLf & _
"For example, if the date of this report is 9-8-17, you would want to use the 'August 2017.xlsx.' report."
' Dialog's Title
strTitle = "Latest Report"
'Display MessageBox
iRet = MsgBox(strPrompt, vbOK, strTitle)
Window3 = Application.GetOpenFilename( _
FileFilter:="Excel Files (*.xls*),*.xls*", _
Title:="Choose previous quarter's file", MultiSelect:=False)
MsgBox "You selected " & Window3
'below is some extra code from where I used this same startegy for VLOOKUP.
'Not sure if this "x" variable will be needed.
lNewBracketLocation = InStrRev(Window2, Application.PathSeparator)
'Edit the string to suit the VLOOKUP formula - insert "["
x = Left$(Window2, lNewBracketLocation) & "[" & Right$(Window2, Len(Window2) - lNewBracketLocation)
Dim wb3 As Workbook
'I want to do all of this WITHOUT opening this next file. Is that possible?
' If I open this file it works. but I am trying to do it without opening.
'Because it takes a minute
'Set wb3 = Workbooks.Open(Window3)
shtName = wb3.Worksheets("Team Members").name
'*******RIGHT here IS WHERE IT ERRORS******************
'Run-time error '91':
'Object variable or With block variable not set
Stop
wb3.Sheets(shtName).Select
ActiveSheet.Range("$A$1:$P$2769").autofilter Field:=1, Criteria1:="Interns"
Range("A2768").Select
Range(Selection, Selection.End(xlDown)).Select
Range(Selection, Selection.End(xlToRight)).Select
Selection.COPY
This is some other code I have that takes the vlookup without actually opening the other file. Can I do kind of the same thing? I can't get it to work.
Dim Window2 As String
Dim x As String
Dim lNewBracketLocation As Long
Window2 = Application.GetOpenFilename( _
FileFilter:="Excel Files (*.xls*),*.xls*", _
Title:="Choose previous quarter's file", MultiSelect:=False)
MsgBox "You selected " & Window2
'Find the last instance in the string of the path separator "\"
lNewBracketLocation = InStrRev(Window2, Application.PathSeparator)
'Edit the string to suit the VLOOKUP formula - insert "["
x = Left$(Window2, lNewBracketLocation) & "[" & Right$(Window2, Len(Window2) - lNewBracketLocation)
shtName = ActiveWorkbook.Worksheets(1).name
Stop
MainWindow.Activate
Columns("B:B").Select
Selection.Delete Shift:=xlToLeft
Range("AI2").FormulaR1C1 = "=VLOOKUP(RC2,'" & x & "]shtName'!R3C2:R9694C49, 23, FALSE)"
Range("AJ2").FormulaR1C1 = "=VLOOKUP(RC2,'" & x & "]shtName'!R3C2:R9694C49, 19, FALSE)"
Range("AK2").FormulaR1C1 = "=VLOOKUP(RC2,'" & x & "]shtName'!R3C2:R9694C49, 20, FALSE)"
Range("AL2").FormulaR1C1 = "=VLOOKUP(RC36,'" & x & "]shtName'!R3C2:R9694C49, 23, FALSE)"
It's impossible to copy cells across from a closed workbook. The vlookups are a different story as Excel caches a copy of the result to display when the external workbook is closed.
Just like what you're trying to do, i.e., you need to have the external file opened once to grab the data. With vlookup it's when the formula is typed/pasted into the sheet. At that time the external workbook must either be open or Excel opens it behind the scenes when you select the file from the Update Values:Book1.xlsm file selection dialog. With your code, it's when you want to grab the data. You must open it for you to cache the data yourself.
However you can solve the time issue by using this:
Application.Calculation = xlCalculationManual
Set wb3 = Workbooks.Open(Window3)
and then after you close the workbook, this:
Application.Calculation = xlCalculationAutomatic

In VBA, my VLOOKUP needs to Update Values

I'm writing a script that requires opening a second workbook and running a VLOOKUP in the second workbook. It works perfectly when the filename of the second workbook is "testlookup.xlsx" but when I changed the filename to "hippity hop 1251225253.xlsx", it opens a window that says "Update Values: 1251225253" and then the VLOOKUP fails. How can I get the code to work regardless of the filename?
fpath = Application.GetOpenFilename(, , "Select the CMS All Assets exported CSV")
fname = Dir(fpath)
Workbooks.Open (fpath)
Set openedBook = Application.ActiveWorkbook
Set assetBook = openedBook.Worksheets(1)
ActiveWindow.WindowState = xlMinimized
checkWkbk.Activate
With dupeSheet
'determine last row
lr = .Cells(Rows.count, 1).End(xlUp).Row
'vlookup from C2:CEnd
.Range(.Cells(2, 3), .Cells(lr, 3)).FormulaR1C1 = _
"=VLOOKUP(RC[-2], " & CStr(fname) & "!C1:C2, 2, FALSE)"
End With
If your description of the filenames is correct, the problem is that you're using a file name with space characters in it, which is throwing the VLookup off. You need to put single-quote characters around the file name in the formula, thus:
"=VLOOKUP(RC[-2], '" & CStr(fname) & "'!C1:C2, 2, FALSE)"
I may be off base with this bit, since you said it works when you don't have spaces in the file names, but you should also include the worksheet name in the formula string, so your formula would look more like this:
"=VLOOKUP(RC[-2], '[" & CStr(fname) & "]" & assetBook.name & "'!C1:C2, 2, FALSE)"
Part of what may be happening is you use the ActiveWorkbook to find the workbook you need versus finding the workbook by the correct name. I use the below subroutine for this purpose:
Sub Get_Workbook_Object(sPath As String, wbHolder As Workbook)
Dim wb As Workbook
If Len(sPath) > 0 Then
ThisWorkbook.FollowHyperlink (sPath)
Else
Exit Sub
End If
For Each wb In Workbooks
If wb.FullName = sPath Then
Set wbHolder = wb
Exit Sub
End If
Next
End Sub
To use this code you could add the subroutine to your module and then call it with something like:
Get_Workbook_Object fPath, openedBook
Also Dir() isn't going to return a fullpath, it is only going to return the appropriate filename. For example, it may return "Hippity Hop.xlsx" instead of "C:Users\Hippity Hop.xlsx" where the first part is the actual filepath. You may want to use something like this instead:
With Application.FileDialog(msoFileDialogFilePicker)
.Title = "Please select the CMS All Assets exported CSV"
.Show
If .SelectedItems.Count = 1 Then
fpath = .SelectedItems(1)
Else
MsgBox "Please choose at least one file"
Exit Sub
End If
End With
This will return the full path of the file.

Excel VBA: Formula Not Entering Correctly From String

I'm trying to finish a script that will allow a user to select another excel file when a cell is double clicked, then that excel file is used to drop in a formula into the main excel file.
I cannot use the cell values alone because being able to see the file path in the formula bar when the script is complete is required. So the issue is that the formula being entered does not match the string text that it should be pulling from.
For clarification, the string I use called FormulaPath ends up being a formula ending "...\00975-006-00[00975-006-00.xls]QuoteDetails'!" and this would be the correct formula.
But when I use this to enter the formula into a range:
Range("A1").Formula = "=" & FormulaPath & "$C$100"
The actual formula ends up being entered as "...[00975-006-00[00975-006-00.xls]Quote Details]00975-006-00[00975-006-00.xls]Q'!$C$100
Notice the repetition?
I'm on mobile right now, so forgive me if the formatting is wacky. Full script below. Thanks!
Option Explicit
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Dim ImportWB, QuoteWB As Workbook
Dim AdInsWS, AdInsCostWS As Worksheet
Dim ImportPathName As Variant
Dim FormulaPath As String
Set QuoteWB = ThisWorkbook
Set AdInsWS = QuoteWB.Sheets("Ad-Ins")
Set AdInsCostWS = QuoteWB.Sheets("Ad-ins cost")
If Not Intersect(Target, Range("B:B")) Is Nothing Then
'set default directory
ChDrive "Y:"
ChDir "Y:\Engineering Management\Manufacturing Sheet Metal\Quotes"
'open workbook selection
ImportPathName = Application.GetOpenFilename(FileFilter:="Excel Files (*.xls*), *.xls*", Title:="Please select a file")
If ImportPathName = False Then 'if no workbook selected
MsgBox "No file selected."
ElseIf ImportPathName = ThisWorkbook.Path & "\" & ThisWorkbook.Name Then 'if quote builder workbook selected
MsgBox "Current quote workbook selected, cannot open."
Else
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Workbooks.Open Filename:=ImportPathName, UpdateLinks:=False
Set ImportWB = ActiveWorkbook
FormulaPath = "'" & ImportWB.Path & "[" & ImportWB.Name & "]Quote Details'!"
AdInsCostWS.Range("B3").Formula = "=" & FormulaPath & "$C$100"
ImportWB.Close
End If
Cancel = True
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End If
End Sub
I got your script to work by simply adding a backslash to the FormulaPath string:
FormulaPath = "'" & ImportWB.Path & "\[" & ImportWB.Name & "]Quote Details'!"
ImportWB.Path is importing the Path with the excel name, split the path string

Excel Exports Extra Commas to CSV

I have a large macro program run through Excel 2010 that, after formatting large amounts of data into another table and exporting the workbook as a CSV file (by large amounts of data I mean thousands of rows, up to over 59,000 rows). Recently, my files have started ending up with an extra row of commas at the end like so:
data,data,data,data,number,date
data,data,data,data,number,date
,,,,,
I am exporting these files to an SQL database using a stored procedure, so ensuring that there are no extra commas to screw with the program is essential. So, with that said, what is happening and how can I prevent it? I can provide any code or information that you believe is missing.
NOTE: It only appears to be happening on files with a couple thousand lines at least of data. One file exported often has 2,000+ and another must have 59,000+ for the table to be exported.
EDIT1: Here's the macro I'm using, just in case it would be helpful (requested by Ditto)
Sub exportTable()
Dim varIsOpen As Boolean
Dim varSaveLocation1 As String, varSaveLocation2 As String
varIsOpen = False
If ThisWorkbook.Sheets("ControlSheet").Range("D2").value = "" Then
varSaveLocation1 = ThisWorkbook.Path & "\CSVREVIEW\"
varSaveLocation2 = varSaveLocation1 & Year(Now) & Month(Now) & Day(Now) & Hour(Now) & Minute(Now)
Else
varSaveLocation1 = ThisWorkbook.Sheets("ControlSheet").Range("D2").value
If Right(varSaveLocation1, 1) <> "\" Then varSaveLocation1 = varSaveLocation1 & "\"
varSaveLocation2 = varSaveLocation1 & Year(Now) & Month(Now) & Day(Now) & Hour(Now) & Minute(Now)
End If
For counter = 1 To Workbooks.Count
If Workbooks(counter).Name = "TableBook.xls" Then varIsOpen = True
If varIsOpen = True Then Exit For
Next
If varIsOpen = False Then GoTo isClosed
Workbooks("TableBook").Activate
Application.DisplayAlerts = False
'Check if TableBook is empty and don't export if so
If Workbooks("TableBook").Sheets("logFile").Range("A1").value = "" Then
Workbooks("TableBook").Close
GoTo isClosed
End If
'On Error Resume Next
If Len(Dir(varSaveLocation1, vbDirectory)) = 0 Then
MkDir varSaveLocation1
End If
If Len(Dir(varSaveLocation2, vbDirectory)) = 0 Then
MkDir varSaveLocation2
End If
'On Error GoTo 0
ActiveWorkbook.Sheets("test").Activate
ActiveWorkbook.SaveAs varSaveLocation2 + "\test", xlCSV
ActiveWorkbook.Sheets("part").Activate
ActiveWorkbook.SaveAs varSaveLocation2 + "\part", xlCSV
ActiveWorkbook.Sheets("logFile").Activate
ActiveWorkbook.SaveAs varSaveLocation2 + "\logFile", xlCSV
ActiveWorkbook.Sheets("deltaLimits").Activate
ActiveWorkbook.SaveAs varSaveLocation2 + "\deltaLimits", xlCSV
ActiveWorkbook.Close
Application.DisplayAlerts = True
isClosed:
End Sub
Tap Ctrl+End to see what Excel believes are the extents of your data. If it is beyond what you want to export, use Home ► Editing ► Clear ► Clear All to wipe all values and formatting from the rows below and the columns to the right of your desired data region and save the workbook. Excel 2010 (with all SPs) will adjust to the CurrentRegion and Ctrl+End should now take you to the correct last cell.
Earlier versions of Excel (or XL2010 without all SPs) may require additional steps (see Unwanted extra blank pages in Excel).
I had an issue which looked the same (extra commas in csv) and it turned out that I was exporting one extra line in my loop and the cells I was using were empty, therefore I got commas only
I had the exactly same problem. If the entire sheet is formatted, even just Text type or Text Height, Excel detects even empty cells as data. You can delete the entire formatted columns/ rows as described above Cœur. Or just create a new sheet without formatting anything and copy your code or change the address.