I am trying to write a Macro in VBA using Excel 2010 that is linked to a button in a worksheet (located in Cell A1). When the button is pressed, a CSV should be generated that deletes columns A and B, so that column C effectively becomes column A. I am trying to also name the newly generated CSV based on the cell contents from cell A30 within the worksheet, but when I run the macro I am getting an error on the SaveAs function. I believe this is because cell A30 is deleted later on in the script. My question is where there is a way to use the Range (A30) to name the new CSV while still deleting that cell later on within the new CSV all within the same sub? I'm still new to VBA, so it is unclear to me why this is an issue when I would think that each command is executed sequentially, so once the CSV is saved with the new name, I would think I'd be able to delete the source of the file name.
Sub rpSaveCSV()
Dim ws As Worksheet
Set ws = ActiveSheet
'Saves current sheet of tracker as a CSV
ws.SaveAs "Y:\Drive\Youth " & Range("A30") & " .csv", FileFormat:=xlCSV
'Copies entire sheet and pastes values to get rid of formulas
ws.Select
Cells.Select
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues
ActiveSheet.Select
Application.CutCopyMode = False
'Deletes first two columns and all remaining columns without content
Range("A:B").EntireColumn.Delete
Range("BI:XFD").EntireColumn.Delete
'Saves panel CSV
ActiveWorkbook.Save
'Opens Tracker up again
Workbooks.Open Filename:="Y:\Drive\Tracker.xlsm"
End Sub
Declare a variable to hold the string value:
Dim filename as String
filename = Range("A30")
'verify that "Y:\Drive\Youth " & filename & " .csv" is a valid file name:
Debug.Print "Y:\Drive\Youth " & filename & " .csv" ' looks right? Ctrl+G to find out
ws.SaveAs "Y:\Drive\Youth " & filename & " .csv", FileFormat:=xlCSV
'...delete columns...
'...do stuff...
Debug.Print filename 'value is still here!
I would recommend learning to use arrays with Excel data. It can often be far simpler than trying to replication Excel Application functions in VBA. And it is far more efficient/fast.
Here is a function that feeds the data to an array, and then prints the array to a csv (text) file.
Sub CreateCsvFromWorkSheet(leftColumn, rightColumn, FileName)
Set ws = ActiveSheet
Set fso = CreateObject("Scripting.FileSystemObject")
Set f = fso.CreateTextFile(FileName, True)
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
ar = ws.Range(ws.Cells(1, leftColumn), ws.Cells(lastRow, rightColumn))
For i = 1 To UBound(ar, 1)
strLine = ""
For j = 1 To UBound(ar, 2)
strLine = strLine & ar(i, j) & ","
Next
strLine = Left(strLine, Len(strLine) - 1)
f.WriteLine strLine
Next
f.Close
End Sub
You can call the function like this:
Sub TestRun()
FileName = "Y:\Drive\Youth " & Range("A30") & " .csv"
CreateCsvFromWorkSheet 3, 60, FileName
MsgBox "Complete."
End Sub
Related
I have multiple worksheets in my workbook.
Each worksheet has two columns of data (ColA and ColC) which I want to print to separate text files.
The attached code results in two text files: “WorksheetTab_LnFn.txt” and “WorksheetTab_FnLn.txt”
The text file saved from my ColA does NOT quotations whilst the second text file saved from my ColC DOES HAVE quotation marks - I want each resulting text file to NOT have quotation marks.
I may have worksheets later with data in ColA, ColC, ColE and ColG, each of which I want to export/save/print to a text file – thus I would want in that case four separate text document, all WITHOUT quotation marks.
The best code I have been able to find is locate is: Write export of selected cells as a .txt file without "quotation marks" and I have looked at How to create a text file using excel VBA without having double quotation marks?.
I understand most of it, but am not being successful at integrating parts of this code into mine. Ideally I am seeking to reduce the code and loop so it would process ColA and then ColB without having two separate code blocks. I did use code I found and made minimal changes, but do not know if the Case LCase line is necessary
'Create FirstName LastName Isolation TXT files
Application.ScreenUpdating = False
Application.DisplayAlerts = False
For Each sh In Sheets
Select Case LCase(sh.Name)
Case LCase("[COLOR=#0000ff]Master[/COLOR]"), LCase("[COLOR=#0000ff]Info[/COLOR]")
Case Else
sh.Range("A:A").Copy
Workbooks.Add
ActiveSheet.Paste
ActiveWorkbook.SaveAs Filename:=ThisWorkbook.Path & "\" & sh.Name & "_FnLn.txt", _
FileFormat:=xlTextMSDOS, CreateBackup:=False
ActiveWorkbook.Close False
End Select
Next
'Create LastName FirstName Isolation TXT files
Application.ScreenUpdating = False
Application.DisplayAlerts = False
For Each sh In Sheets
Select Case LCase(sh.Name)
Case LCase("[COLOR=#0000ff]Master[/COLOR]"), LCase("[COLOR=#0000ff]Info[/COLOR]")
Case Else
sh.Range("C:C").Copy
Workbooks.Add
ActiveSheet.Paste
ActiveWorkbook.SaveAs Filename:=ThisWorkbook.Path & "\" & sh.Name & "_LnFn.txt", _
FileFormat:=xlTextMSDOS, CreateBackup:=False
ActiveWorkbook.Close False
End Select
Next
MsgBox "Text Files Created"
End Sub
This should do what you want:
Sub Tester()
Dim filename As String, myrng As Range, sh As Worksheet, wb As Workbook
Set wb = ThisWorkbook
For Each sh In wb.Worksheets
filename = wb.Path & "\" & sh.Name & "_FnLn.txt"
Set myrng = sh.Range("C1:C" & sh.Cells(sh.Rows.Count, "C").End(xlUp).Row) 'use sh reference
RangeToTextFile myrng, filename 'comma-separated
'RangeToTextFile myrng, filename, vbtab 'e.g. for tab-separated file
Next
MsgBox "Text Files Created"
End Sub
'write a range `rng` to a text file at `fPath`. Default separator is comma
Sub RangeToTextFile(rng As Range, fPath As String, Optional separator As String = ",")
Dim data, r As Long, c As Long, sep, lo As String, ff As Integer
ff = FreeFile() 'safer than using hard-coded #1
Open fPath For Output As #ff
If rng.Cells.CountLarge = 1 Then
ReDim data(1 To 1, 1 To 1) 'handle special case of single cell
data(1, 1) = rng.Value
Else
data = rng.Value 'get all values as an array
End If
For r = 1 To UBound(data, 1) 'loop rows
lo = "" 'clear line output
sep = "" 'clear separator
For c = 1 To UBound(data, 2) 'loop columns
lo = lo & sep & data(r, c) 'build the line to be written
sep = separator 'add separator after first value
Next c
Print #ff, lo 'write the line
Next r
Close #ff
End Sub
First of all I'd like to preface this by saying that I have less than a week's experience using VBA.
I have been trying to create a script that merges PDFs that are linked in an Excel sheet. The code that I have works fine, however, when I add multiple tables separated by empty rows, the script will continue to move down through the empty cells and collect the PDFs from the next table as well.
So if I select the bottom table to merge, it will work fine, but if I select the top one, it will merge all the linked PDFs for ALL the tables moving down.
Here is a screenshot of the Excel sheet I have at the moment:
Excel Sheet
What I would like is for the script to stop at the first empty cell it encounters while moving down column D, rather than continuing until the last populated cell. Meaning that the script will only merge one table of PDFs.
As I said, this is my first week using any VBA, so I have been struggling to get the range for the PDF merging to end when it encounters the empty cell.
Any help would be greatly appreciated!
Sub Button9_Click()
'References
'Adobe Acrobat 10.0 Type Library
Dim objCAcroPDDocDestination As Acrobat.CAcroPDDoc
Dim objCAcroPDDocSource As Acrobat.CAcroPDDoc
Dim PDFfiles As Range, PDFfile As Range
Dim n As Long
Dim em As String
'Set start point of cell range
'Takes ActiveCell from search results and offsets to filepaths
'CURRENTLY LOOKS FOR LAST POPULATED CELL IN COLUMN, DISREGARDING PREVIOUS EMPTY CELLS
With ActiveSheet
Set PDFfiles = .Range(ActiveCell.Offset(3, 1), .Cells(.Rows.Count, "D").End(xlUp))
End With
'Create Acrobat API objects
Set objCAcroPDDocDestination = CreateObject("AcroExch.PDDoc")
Set objCAcroPDDocSource = CreateObject("AcroExch.PDDoc")
'Open first PDF file and merge other PDF files into it
n = 0
For Each PDFfile In PDFfiles
n = n + 1
If n = 1 Then
objCAcroPDDocDestination.Open PDFfile.Value
Else
objCAcroPDDocSource.Open PDFfile.Value
If Not objCAcroPDDocDestination.InsertPages(objCAcroPDDocDestination.GetNumPages - 1, objCAcroPDDocSource, 0, objCAcroPDDocSource.GetNumPages, 0) Then
MsgBox "Error merging" & PDFfile.Value
End If
objCAcroPDDocSource.Close
End If
Next
'Save merged PDF files as a new file
objCAcroPDDocDestination.Save 1, "C:\Users\USER\OneDrive\TEST MERGE\Output\" & Sheets("SEARCH").Range("E6").Value & ".pdf"
objCAcroPDDocDestination.Close
Set objCAcroPDDocSource = Nothing
Set objCAcroPDDocDestination = Nothing
'Opens dialogue box for successful/failed merge
MsgBox "Created New PDF (" & Sheets("SEARCH").Range("E6").Value & ")" & vbCrLf & vbCrLf & "File Path: C:\Users\USER\OneDrive\TEST MERGE\Output\" & Sheets("SEARCH").Range("E6").Value & ".pdf"
'Opens merged PDF
ActiveWorkbook.FollowHyperlink "C:\Users\USER\OneDrive\TEST MERGE\Output\" & Sheets("SEARCH").Range("E6").Value & ".pdf"
End Sub
Try the next code, please:
Sub MergePDFDocuments()
'References to 'Adobe Acrobat 10.0 Type Library
Dim objCAcroPDDocDestination As Acrobat.CAcroPDDoc, objCAcroPDDocSource As Acrobat.CAcroPDDoc, i As Long
Dim PDFfiles As Range, PDFfile As Range, n As Long, em As String, processArr As String, prRng As Range
Dim sh As Worksheet, startRow As Long, endRow As Long
Set sh = ActiveSheet 'use here your sheet
processArr = "A" 'the group files to be processed.
'It can be "B", or other letter if the workbook will be filled with other groups
'CURRENTLY LOOKS FOR LAST POPULATED CELL IN COLUMN, DISREGARDING PREVIOUS EMPTY CELLS
'Set PDFfiles = sh.Range(sh.Offset(3, 1), sh.cells(rows.count, "D").End(xlUp))
endRow = sh.cells(rows.count, "D").End(xlUp).row
For i = 2 To endRow
If sh.Range("C" & i).value = "PRODUCT " & processArr Then
startRow = i + 2: Exit For
End If
Next i
If startRow >= i Then MsgBox "Strange..." & vbCrLf & _
"The area to be prcessed ""PRODUCT " & processArr & """ could not be found.": Exit Sub
'Create Acrobat API objects
Set objCAcroPDDocDestination = CreateObject("AcroExch.PDDoc")
Set objCAcroPDDocSource = CreateObject("AcroExch.PDDoc")
'Open first PDF file and merge other PDF files into it
For i = startRow To endRow
n = n + 1
If sh.Range("D" & i).value = "" Then Exit For 'iteration is interrupted in case of an empty cell in D:D:
If n = 1 Then
objCAcroPDDocDestination.Open sh.Range("D" & i).value
Else
objCAcroPDDocSource.Open sh.Range("D" & i).value
If Not objCAcroPDDocDestination.InsertPages(objCAcroPDDocDestination.GetNumPages - 1, _
objCAcroPDDocSource, 0, objCAcroPDDocSource.GetNumPages, 0) Then
MsgBox "Error merging: " & sh.Range("D" & i).value
End If
objCAcroPDDocSource.Close
End If
Next i
'Save merged PDF files as a new file. Here the pdf name can be assorted with the area to be processed (for instance PRODUCT A):
objCAcroPDDocDestination.Save 1, "C:\Users\USER\OneDrive\TEST MERGE\Output\" & Sheets("SEARCH").Range("E6").value & ".pdf"
objCAcroPDDocDestination.Close
Set objCAcroPDDocSource = Nothing
Set objCAcroPDDocDestination = Nothing
'Opens dialogue box for successful/failed merge
MsgBox "Created New PDF (" & Sheets("SEARCH").Range("E6").value & ")" & vbCrLf & vbCrLf & "File Path: C:\Users\USER\OneDrive\TEST MERGE\Output\" & Sheets("SEARCH").Range("E6").value & ".pdf"
'Opens merged PDF
ActiveWorkbook.FollowHyperlink "C:\Users\USER\OneDrive\TEST MERGE\Output\" & Sheets("SEARCH").Range("E6").value & ".pdf"
End Sub
You must set processArr to be processed (A or B from your picture).
Code is not tested, but it should work. Please test it and send some feedback.
after converting my sheet into prn it gives error during upload on my erp ,when i convert prn into txt format i saw some kind of chinese written how to fix this problem. below code add value +1 in row "A" and convert into prn
Sub CONVERT()
Dim vcounter As Long
Dim ws As Worksheet
For Each ws In Sheets
ws.Activate
vcounter = 2
While Range("A" & vcounter).Value <> ""
Range("a" & vcounter).Value = Range("a" & vcounter).Value + 1
vcounter = vcounter + 1
Wend
Application.DisplayAlerts = False
ActiveSheet.SaveAs Filename:="D:\birla soft\" & ActiveSheet.Name & ".prn"
Next ws
End Sub
You're saving a .xlsm/.xlsx file with a .prn extension; that doesn't make it a .prn file, it's still a .xlsm/.xlsx file - the extension isn't what determines the file's format, it's just a convenient indicator for us puny humans to recognize what we're looking at when we browse through files. You want to supply a xlTextPrinter XlFileFormat argument to the SaveAs method:
ActiveSheet.SaveAs Filename:="D:\birla soft\" & ActiveSheet.Name & ".prn", xlTextPrinter
A note about this:
ws.Activate
You don't need it. Instead, qualify these Range calls with the ws object - and you want to iterate the Worksheets collection (Sheets may contain all kinds of non-worksheet sheet types):
For Each ws In ActiveWorkbook.Worksheets ' or did you mean to iterate sheets in ThisWorkbook?
Do While ws.Range(...)
ws.Range(...) = ws.Range(...) + 1
vcounter = vcounter + 1
Loop
Application.DisplayAlerts = False
ws.SaveAs FileName:="..." & ws.Name & ".prn", FileFormat:=xlTextPrinter
Next
I am looking to have my Macro save a new sheet that i created as a .txt file. this is the code i have so far.
Sub Move()
'
' Move Macro
'
' Keyboard Shortcut: Ctrl+m
'
Sheets("Sheet1").Select
Range("A1").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Workbooks.Add
ActiveSheet.Paste
ActiveWorkbook.SaveAs Filename:="e:" & _
"HDR" + Format(Now(), "YYYYMMDDhhmmss") & ".txt"
End Sub
That includes my macro. I am having trouble with the last part where it saves as a .txt file.
I am currently getting a bunch of crap on my .txt file, here is an example,
"PK ! !}ñU{ Š [Content_Types].xml ¢( ÌTÝNÂ0¾7ñ–Þš€‰1†Á…⥒ˆPÚ3¶ÐµMOÁñöž•Ÿ¨".
Any help would be great.
Manually changing the extension of the file name does not actually change the file type. The SaveAs method takes a file type argument. The code you want is
ActiveWorkbook.SaveAs Filename:="e:" & "HDR" + Format(Now(), "YYYYMMDDhhmmss") _
& ".txt", FileFormat:= xlTextWindows
Doing a search from within Excel help for XlFileFormat will get you (almost) the full list of possible file formats, including 6 text formats, and 4 CSV formats.
Adding txt to the name does not automatically encode the word document into plain text format.
Instead attempt
ActiveWorkbook.SaveAs Filename:="e:" & _
"HDR" + Format(Now(), "YYYYMMDDhhmmss") & ".txt", FileFormat:=wdFormatText, Encoding:=1252
The ActiveWorkbook.SaveAs method adds double quote to the beginning and end of every line in the file.
This method parses each line from a given range and transforms it into a CSV file:
Sub SaveSheetToCSVorTXT()
Dim xFileName As Variant
Dim rng As Range
Dim DelimChar As String
DelimChar = "," 'The delimitation character to be used in the saved file. This will be used to separate cells in the same row
xFileName = Application.GetSaveAsFilename(ActiveSheet.Name, "CSV File (*.csv), *.csv, Text File (*.txt), *.txt")
If xFileName = False Then Exit Sub
If Dir(xFileName) <> "" Then
If MsgBox("File '" & xFileName & "' already existe. Overwrite?", vbYesNo + vbExclamation) <> vbYes Then Exit Sub
Kill xFileName
End If
Open xFileName For Output As #1
'Save range contents. Examples of ranges:
'Set rng = Activesheet.Range("A1:D4") 'A rectangle between 2 cells
'Set rng = Activesheet.columns(1) 'An entire column
Set rng = ActiveSheet.Range("B14").CurrentRegion 'The "region" from a cell. This is the same as pressing CTRL+T on the selected cell
For i = 1 To rng.Rows.Count
For j = 1 To rng.Columns.Count
lineText = IIf(j = 1, "", lineText & DelimChar) & rng.Cells(i, j)
Next j
Print #1, lineText
Next i
Close #1
MsgBox "File saved!"
End Sub
I am quite new with VBA and trying to create a VBA which copy/paste specific ranges from multiple files (.xlsm) selected by a user into a master excel file. Basically I want to summarize the results for different scenarios into one excel file.
Until now, I have searched abit and managed to write a code which asks the files to be important. My problem is: I cant activate those files and start copy/pasting specific values into the master file.
I really appreciate if you can help me solve this. If you have a different idea, then it is also welcome. Many thanks..
Sub GetImportValues()
Dim finfo As String
Dim filterindex As String
Dim title As String
Dim filenames As Variant
Dim I As Integer
'Set up list of file filters
finfo = "Excel VBA files (*.xlsm), *.xlsm,"
filterindex = 1
'Set the dialog box caption
title = "pls select the excel files to Import"
'Get the filename
filenames = Application.GetOpenFilename(MultiSelect:=True)
If IsArray(filenames) Then
'Display full path and name of the files
Msg = "You selected:" & vbNewLine
For I = LBound(filenames) To UBound(filenames)
Msg = Msg & filenames(I) & vbNewLine
Next I
MsgBox Msg
Else
MsgBox "No excel file was selected."
End If
' start copy/pasting files one by one
For I = 1 To 10
Workbooks.Open filenames
Sheets("Report Tables").Range("D3").Select
Copy.Range (Selection.Offset(0, 11))
ThisWorkbook.Sheets("Results").Activate
Range("A3").PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Next I
End Sub
Try this code:
Sub GetImportValues()
Dim filenames, f
Dim myMsg As String
Dim wb As Workbook
Dim lastrow As Long
'Get the filename
filenames = Application.GetOpenFilename(FileFilter:="Excel VBA files (*.xls*), *.xls*", _
filterindex:=1, _
title:="pls select the excel files to Import", _
MultiSelect:=True)
If IsArray(filenames) Then
myMsg = "You selected:" & vbNewLine
'Display full path and name of the files
For Each f In filenames
myMsg = myMsg & f & vbNewLine
Next f
MsgBox myMsg
Else
MsgBox "No excel file was selected."
Exit Sub
End If
For Each f In filenames
Set wb = Workbooks.Open(f)
With ThisWorkbook.Sheets("Results")
'determine last non empty row in column A sheet "Result" to past result
lastrow = Application.Max(3, .Cells(.Rows.Count, "A").End(xlUp).Row + 1)
.Range("A" & lastrow).Value = wb.Sheets("Report Tables").Range("O3").Value
End With
wb.Close SaveChanges:=False
Set wb = Nothing
Next f
End Sub
Code above copies cell O3 from each workbook and paste it in Result sheet of ThisWorkbook in A3 for first file (actually it finds last non empty row), in A4 for second file and so on