I am using the below code to create a .txt file from an excel sheet. However it seems to produce another column at the start of the file and I cannot figure out why. Any Help would be appreciated.
A9:M287 are all filled with content also so it is not a hidden blank column.
Sub StoretoTXT()
Dim answer As Integer
answer = MsgBox("Have all the required fields been filled and are correct?", vbYesNo + vbQuestion, "Data Check")
If answer = vbYes Then
Dim c As Range, r As Range
Dim output As String
For Each r In Range("A9:M287").Rows
For Each c In r.Cells
output = output & vbTab & c.Value
Next c
output = output & vbNewLine
Next r
Open "C:\Test\Desktop" & Format(Now(), "YYYYMMDDHHMMSS") & "Test.txt" For Output As #1
Print #1, output
Close
MsgBox "File has now been created. Excel will now close"
ActiveWorkbook.Close False
Else
'do nothing
End If
End Sub
It might be easier to just use the SaveAs method to create a tab-delimited file. Since you're looking only for specific range, first copy that range to a new workbook, and then save as xlText:
Sub SaveAsTabDelimited()
Dim rng as Range
Dim newWB as Workbook
Set rng = Range("A9:M287")
Set newWB = Workbooks.Add
Application.DisplayAlerts = False
With newWB
Do While .Worksheets.Count > 1
.Worksheets(.Worksheets.Count).Delete
Loop
End With
rng.Copy newWB.Worksheets(1).Range("A1")
'## Modify path to file output in the next line:
newWB.SaveAs Filename:="C:\Debug\tab-delimited.txt", FileFormat:= _
xlText, CreateBackup:=False
Application.DisplayAlerts = True
newWB.Close
End Sub
Related
I've got an Excel report with a table and I need to export a single column from that table to a txt file. I'm calculating the file name that I want to use for the txt file based on fields in the spreadsheet so I want to use that field as my file name.
The data I want to export is in column S.
The file name I want to use is in cell E5 and contains the file extension of txt as well.
This is what I have so far:
Sub FileNameAsCellContent()
Dim FileName As String
Dim Path As String
Application.DisplayAlerts = False
Path = "C:\temp\"
FileName = Range("E5").Value & ".txt"
ActiveWorkbook.SaveAs Path & FileName, xlTextWindows
Application.DisplayAlerts = True
MsgBox "Export Complete. Click OK to continue"
End Sub
This works but it's exporting the entire worksheet and I only need one column out of the table.
This sub will save the data in Sheet1, column S to a text file.
Sub FileNameAsCellContent()
Dim wsSource As Worksheet
Dim fileName As String
Dim wsDest As Worksheet
Dim wbDest As Workbook
Set wsWource = Worksheets("Sheet1")
fileName = "C:\temp\" & wsSource.Cells("E5").Value & ".txt"
' Create a new worksheet.
Set wsDest = Worksheets.Add
' Copy data from column S to new worksheet
wsSource.Range("S:S").Copy
wsDest.Range("A:A").PasteSpecial xlPasteValues
' Worksheet.Move with no arguments will
' copy the worksheet to a new workbook
' and remove it from the current workbook.
wsDest.Move
' Grab a reference to the new workbook.
With Workbooks
Set wbDest = .Item(.Count)
End With
' Save new workbook as text file & close.
Application.DisplayAlerts = False
wbDest.SaveAs fileName, xlTextWindows
wbDest.Close False
Application.DisplayAlerts = True
End Sub
Export Column to Textfile
Sub FileNameAsCellContent()
Dim Path As String
Dim FileName As String
Path = "C:\temp\"
FileName = Range("E5").Value & ".txt"
Application.ScreenUpdating = False
Columns("S").Copy
With Workbooks.Add
.Worksheets(1).Columns("A").PasteSpecial
Application.DisplayAlerts = False
.SaveAs Path & FileName, xlTextWindows
.Close False
Application.DisplayAlerts = True
End With
Application.ScreenUpdating = True
MsgBox "Export Complete. Click OK to continue"
End Sub
Using a TextStream Object
Option Explicit
Sub Export()
Const SHT_NAME = "Customer_Class_Clean-Up_Report"
Const RNG_NAME = "H7" ' cell
Const TABLENAME = "Table_Query_from_CHECKMATE"
Const COL = "Yard,AccountNum,CustomerCategory"
Const FOLDER = "C:\temp\"
Dim ws As Worksheet, rng As Range, cell As Range
Dim filename As String, n As Long
Dim FSO As Object, ts As Object
Set FSO = CreateObject("Scripting.FileSystemObject")
' build export filename
Set ws = ThisWorkbook.Sheets(SHT_NAME)
filename = FOLDER & ws.Range(RNG_NAME).Value
If Len(filename) = 0 Then
MsgBox "Filename is blank", vbCritical
Exit Sub
End If
filename = filename & ".txt"
' create text file
Set ts = FSO.createTextfile(filename, True, True) 'overwrite, unicode
Set rng = ws.Range(TABLENAME & "[[#Headers],[" & COL & "]]")
For Each cell In ws.Range(rng, rng.End(xlDown))
ts.writeline cell
n = n + 1
Next
' finish
ts.Close
MsgBox n & " Rows exported from " & rng.Address & vbCrLf & _
" to " & filename, vbInformation, "Click OK to continue."
End Sub
I used the following and it will work for what I need. It's copying the table content that I need, pasting it in a sheet called "ForExport" and then saving the content in that worksheet with the file name I need.
Sub Export()
Application.ScreenUpdating = False
Sheets("ForExport").Visible = True
Sheets("ForExport").Select
Columns("A:A").Select
Selection.Delete Shift:=xlToLeft
Sheets("Customer_Class_Clean-Up_Report").Select
Range( _
"Table_Query_from_CHECKMATE[[#Headers],[Yard,AccountNum,CustomerCategory]]"). _
Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Sheets("ForExport").Select
Range("A1").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
Range("A1").Select
Sheets("ForExport").Select
Dim FileName As String
Dim Path As String
Sheets("Customer_Class_Clean-Up_Report").Select
Path = "C:\temp\"
FileName = Range("H7").Value & ".txt"
Sheets("ForExport").Select
ActiveWorkbook.SaveAs Path & FileName, xlTextPrinter
'ActiveWorkbook.Close SaveChanges:=True
Sheets("Customer_Class_Clean-Up_Report").Select
Range("B5").Select
MsgBox "Export complete. File is located in the C:\temp directory. Click OK to continue."
End Sub
I have written VBA code in excel to copy a specific range on one tab and paste it to a new workbook which saves automatically.
However, the program I am inputting this file to is erroring because of one line that needs to be in text format. I am assuming I can just change the entire data set to text format and it would relieve my issues. The code is below. It has no other issues at the moment. I work at a public accounting firm so I have no idea what I am doing besides what I found on google.
Sub Reset()
Worksheets("Time Entry").Range("f11:j550").ClearContents
End Sub
Sub copypaste()
Set originalSheet = ActiveSheet
Set NewSheet = Sheets.Add(After:=ActiveSheet)
ActiveSheet.Name = Format(Date, "MM.DD.YY")
NewSheet.Range("a1:m490").Value = originalSheet.Range("q9:ac490").Value
ActiveSheet.Range("A:M").Columns.AutoFit
Dim lr As Integer
Dim i As Integer
lr = Cells(Rows.Count, 3).End(xlUp).Row
For i = lr To 6 Step -1
Debug.Print i
If IsError(Range("c" & i).Value) Then
Rows(i).EntireRow.Delete
End If
Next i
ActiveSheet.Move
Set NewWb = ActiveWorkbook
ActiveWorkbook.SaveAs Filename:=Environ("USERPROFILE") & "\Desktop\Time Tracker\" & NewFileName & Format(Date, "MM.DD.YY") & ".xlsx", FileFormat:=xlOpenXMLWorkbook
Exit Sub
ThisWorkbook.Close SaveChanges:=False
ErrorTrap:
MsgBox "Invalid directory. You must correct the path or save manually."
Resume Next
End Sub
I have a list of *.xlsm file names on a sheet named "DB" in range E961 to E1010 (50 rows) and I'm trying to create a macro that runs through this list and open the corresponding files in the set directory, runs some code and close the file, moving on to the next file on the list - repeating this operation every 5 minutes.
The directory contains 400+ xlsm files, and the list in E961 will typically be less than 50 files - so I'm not trying to open all the files in the directory. That already happens once a day at a set time.
But I am trying to open these "shortlisted" files and update them every 5 minutes for example. I tried different combinations of code but can't seem to get it working.
The main file containing this code is also in the same directory to allow relative linking to the other 400+ files, hence the ThisWorkbook.Path code.
Edited code below:
Sub UPDATE()
Application.ScreenUpdating = True
With ThisWorkbook.Worksheets("DB")
Dim inputRange As Range
Set inputRange = .Range("E961", .Cells(.Rows.Count, 5).End(xlUp))
End With
Dim directory As String: directory = ThisWorkbook.Path & "\"
Dim fileName As String
Dim r As Range
Dim xlwb As Workbook
For Each r In inputRange
If r <> vbNullString Then
fileName = Dir(directory & r & ".xl??*")
Set xlwb = Workbooks.Open(directory & fileName)
Application.DisplayAlerts = False
ActiveWorkbook.RefreshAll
If Range("A4") > Sheets("DB").Cells(Rows.Count, "A").End(xlUp).Offset(0) Then
Worksheets("DB").Range("A4:L4").Select
Worksheets("DB").Range("A4").Activate
Selection.Copy
Sheets("DB").Select
Sheets("DB").Cells(Rows.Count, "A").End(xlUp).Offset(1). _
PasteSpecial Paste:=xlPasteValues, _
SkipBlanks:=True, Transpose:=False
Application.CutCopyMode = False
Else
End If
If Range("A4") = Sheets("DB").Cells(Rows.Count, "A").End(xlUp).Offset(0) Then
Worksheets("DB").Range("A4:L4").Select
Worksheets("DB").Range("A4").Activate
Selection.Copy
Sheets("DB").Select
Sheets("DB").Cells(Rows.Count, "A").End(xlUp).Offset(0). _
PasteSpecial Paste:=xlPasteValues, _
SkipBlanks:=True, Transpose:=False
Application.CutCopyMode = False
End If
xlwb.Close True
End If
Next r
Application.ScreenUpdating = True
End Sub
The error comes from "Set xlwb = (sht.Cells(Row, 1).Value)" because it is trying to open a sheet as a workbook, but I have no idea how to fix it... or everything is wrong ...
Thanks for the help!
Try this piece it should work thought it will only open and close workbooks until you give it some code to work them:
Option Explicit
Sub UPDATE()
Application.ScreenUpdating = False
'if you are only using here your wb and sht variables, use a With, there is no need to use variables
With ThisWorkbook.Worksheets("DB")
Dim inputRange As Range
'It is preferable to do xlUp because you could find some empty cells in between.
Set inputRange = .Range("E961", .Cells(.Rows.Count, 5).End(xlUp))
End With
Dim directory As String: directory = ThisWorkbook.Path & "\"
Dim fileName As String
Dim r As Range
Dim xlwb As Workbook
For Each r In inputRange
If r <> vbNullString Then
fileName = Dir(directory & r & ".xl??*") 'don't know if your cell has the extension
Set xlwb = Workbooks.Open(directory & fileName)
'some code
xlwb.Close False 'False won't save the workbook, use True if you want it to be saved.
End If
Next r
Application.ScreenUpdating = True
End Sub
I'm trying to copy a range of cells from a closed Workbook to the current Workbook but I always get ERROR 1004. The code I'm using is as follows:
Sub Sheet2()
Dim Filt As String
Dim FilterIndex As Integer
Dim Title As String
Dim Multi As Boolean
Dim DataFile
Dim WBdata As Workbook
'I prompt the user to select the file to import
Filt = "Excel Workbook 2010 (*.xlsx),*.xlsx," & "Excel Workbook (*.xls), *.xls," & "All Files (*.*),*.*"
FilterIndex = 1
Title = "Select file to import"
Multi = False
DataFile = Application.GetOpenFilename(FileFilter:=Filt, FilterIndex:=FilterIndex, Title:=Title, MultiSelect:=Multi)
If DataFile = False Then
MsgBox "No file was selected"
End If
'Open the file selected by the user
Set WBdata = Workbooks.Open(DataFile)
'Get the data
WBdata.Activate
Sheets("Sheet1").Range(Cells(4, 1), Cells(4, 1).End(xlDown).Offset(-1, 0)).Copy _ ThisWorkbook.Sheets("Sheet2").Columns(1)
ThisWorkbook.Sheets("Sheet2").Activate
ThisWorkbook.Sheets("Sheet2").Columns(1).Select
Selection.EntireColumn.AutoFit
'Close and Select Cell (1,1)
WBdata.Close
ThisWorkbook.Sheets("Manager").Activate
ThisWorkbook.Sheets("Manager").Cells(1, 1).Select
End Sub
The debugger stops in Sheets("Sheet1").Range(Cells(4, 1), Cells(4, 1).End(xlDown).Offset(-1, 0)).Copy _ ThisWorkbook.Sheets("Sheet2").Columns(1).
I tried the same syntax in a Test file and it went smooth but I cannot make it happen on the actual file. This is the code in the Test file:
Sheets("Sheet1").Range(Cells(1, 1), Cells(1, 1).End(xlDown).Offset(-1, 0)).Copy ThisWorkbook.Sheets("Sheet1").Columns(2)
I appreciate all your help, thanks!
Two things
You might want to exit the sub after MsgBox "No file was selected" so that the code doesn't give an error in this line Set WBdata = Workbooks.Open(DataFile) if say the user cancelled the dialog box? Or Handle the code in the Else part of the If Statement as shown in the code below
You are getting that error because you have not fully qualified the cells for example see the .(DOT) in Cells(1, 1) in the code below
Your code can be re-written as (UNTESTED)
Sub Sheet2()
Dim Filt As String, Title As String
Dim FilterIndex As Integer
Dim Multi As Boolean
Dim DataFile
Dim WBdata As Workbook, ws As Worksheet
Filt = "Excel Workbook 2010 (*.xlsx),*.xlsx," & _
"Excel Workbook (*.xls), *.xls," & _
"All Files (*.*),*.*"
FilterIndex = 1
Title = "Select file to import"
Multi = False
DataFile = Application.GetOpenFilename(FileFilter:=Filt, _
FilterIndex:=FilterIndex, _
Title:=Title, _
MultiSelect:=Multi)
If DataFile = False Then
MsgBox "No file was selected"
Else
'Open the file selected by the user
Set WBdata = Workbooks.Open(DataFile)
Set ws = WBdata.Sheets("Sheet2")
'Get the data
With ws
.Range(.Cells(4, 1), .Cells(4, 1).End(xlDown).Offset(-1, 0)).Copy _
ThisWorkbook.Sheets("Sheet2").Columns(1)
ThisWorkbook.Sheets("Sheet2").Columns(1).EntireColumn.AutoFit
'Close and Select Cell (1,1)
WBdata.Close SaveChanges:=False
End With
End If
End Sub
I have a template file which will be sent out to all subsidiaries of my company.
The template has a tab named start and one named end.
The subsidiaries will place a variable number of template submission sheets between these two names sheets and send them in to me to consolidate into one sheet in my consolidation file.
I have written macros to copy each sheet into the consolidation file, but I currently need to run it sheet by sheet as I don't know how to loop.
The copy macro sits in my Personal.xls file and the paste macro sits in the consolidation sheet.
The loop macro would need to work between the Source file (could be any name) and the consolidation file which is called Consolidation.xls.
Once all sheets are copied from a source file, I then open the next source file and start again, so macro would need to forget the old source file and remember the new one.
This could literally save me hours each week if I could get a macro to work, so any help much appreciated.
I think this is along the lines of what you are chasing. If all your templates are in a single folder, and each have a "start" and "end" sheet then this code will collate them into either
A new workbook with a unique sheet for each relevant sheet in each template
Into a single sheet in a new workbook
I have updated my code from "Collating worksheets from one or more workbooks into a summary file", http://www.experts-exchange.com/A_2804.html to cater for your "start" and "end" sheets
Please post if you need (or have) further detail
Public Sub ConsolidateSheets()
Dim Wb1 As Workbook
Dim Wb2 As Workbook
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim ws3 As Worksheet
Dim rng1 As Range
Dim rng2 As Range
Dim rng3 As Range
Dim rngArea As Range
Dim lrowSpace As Long
Dim lSht As Long
Dim lngCalc As Long
Dim lngRow As Long
Dim lngCol As Long
Dim X()
Dim bProcessFolder As Boolean
Dim bNewSheet As Boolean
Dim StrPrefix
Dim strFileName As String
Dim strFolderName As String
'variant declaration needed for the Shell object to use a default directory
Dim strDefaultFolder As Variant
bProcessFolder = (MsgBox("Process a single folder (Yes)," & vbNewLine & "or single file (No)", vbYesNo, "Application Scope: Folder or single File") = vbYes)
bNewSheet = (MsgBox("Extract all data to a single sheet (Yes)," & vbNewLine & "or a target file sheet for each source sheet (No)", vbYesNo, "Output Format: Single sheet or sheet by sheet collection") = vbYes)
If Not bProcessFolder Then
If Not bNewSheet Then
MsgBox "There isn't much point creating a exact replica of your source file :)"
Exit Sub
End If
End If
'set default directory here if needed
strDefaultFolder = "C:\"
'If the user is collating all the sheets to a single target sheet then the row spacing
'to distinguish between different sheets can be set here
lrowSpace = 1
If bProcessFolder Then
strFolderName = BrowseForFolder(strDefaultFolder)
'Look for xls, xlsx, xlsm files
strFileName = Dir(strFolderName & "\*.xls*")
Else
strFileName = Application _
.GetOpenFilename("Select file to process (*.xls*), *.xls*")
End If
Set Wb1 = Workbooks.Add(1)
Set ws1 = Wb1.Sheets(1)
If Not bNewSheet Then ws1.Range("A1:B1") = Array("workbook name", "worksheet count")
'Turn off screenupdating, events, alerts and set calculation to manual
With Application
.DisplayAlerts = False
.EnableEvents = False
.ScreenUpdating = False
lngCalc = .Calculation
.Calculation = xlCalculationManual
End With
'set path outside the loop
StrPrefix = strFolderName & IIf(bProcessFolder, "\", vbNullString)
Do While Len(strFileName) > 0
'Provide progress status to user
Application.StatusBar = Left("Processing " & strFolderName & "\" & strFileName, 255)
'Open each workbook in the folder of interest
Set Wb2 = Workbooks.Open(StrPrefix & strFileName)
If Not bNewSheet Then
'add summary details to first sheet
ws1.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0) = Wb2.Name
ws1.Cells(Rows.Count, "A").End(xlUp).Offset(0, 1) = Wb2.Sheets.Count
End If
For Each ws2 In Wb2.Sheets
If ws2.Index > Wb2.Sheets("start").Index And ws2.Index < Wb2.Sheets("end").Index Then
If bNewSheet Then
'All data to a single sheet
'Skip importing target sheet data if the source sheet is blank
Set rng2 = ws2.Cells.Find("*", ws2.[a1], xlValues, , xlByRows, xlPrevious)
If Not rng2 Is Nothing Then
Set rng1 = ws1.Cells.Find("*", ws1.[a1], xlValues, , xlByRows, xlPrevious)
'Find the first blank row on the target sheet
If Not rng1 Is Nothing Then
Set rng3 = ws2.Range(ws2.UsedRange.Cells(1), ws2.Cells(rng2.Row, "A"))
'Ensure that the row area in the target sheet won't be exceeded
If rng3.Rows.Count + rng1.Row < Rows.Count Then
'Copy the data from the used range of each source sheet to the first blank row
'of the target sheet, using the starting column address from the source sheet being copied
ws2.UsedRange.Copy ws1.Cells(rng1.Row + 1 + lrowSpace, ws2.UsedRange.Cells(1).Column)
Else
MsgBox "Summary sheet size exceeded. Process stopped on " & vbNewLine & _
"sheet: " & ws2.Name & vbNewLine & "of" & vbNewLine & "workbook: " & Wb2.Name
Wb2.Close False
Exit Do
End If
'colour the first of any spacer rows
If lrowSpace <> 0 Then ws1.Rows(rng1.Row + 1).Interior.Color = vbGreen
Else
'target sheet is empty so copy to first row
ws2.UsedRange.Copy ws1.Cells(1, ws2.UsedRange.Cells(1).Column)
End If
End If
Else
'new target sheet for each source sheet
ws2.Copy after:=Wb1.Sheets(Wb1.Sheets.Count)
'Remove any links in our target sheet
With Wb1.Sheets(Wb1.Sheets.Count).Cells
.Copy
.PasteSpecial xlPasteValues
End With
On Error Resume Next
Wb1.Sheets(Wb1.Sheets.Count).Name = ws2.Name
'sheet name already exists in target workbook
If Err.Number <> 0 Then
'Add a number to the sheet name till a unique name is derived
Do
lSht = lSht + 1
Set ws3 = Wb1.Sheets(ws2.Name & " " & lSht)
Loop While Not ws3 Is Nothing
lSht = 0
End If
On Error GoTo 0
End If
End If
Next ws2
'Close the opened workbook
Wb2.Close False
'Check whether to force a DO loop exit if processing a single file
If bProcessFolder = False Then Exit Do
strFileName = Dir
Loop
'Remove any links if the user has used a target sheet
If bNewSheet Then
With ws1.UsedRange
.Copy
.Cells(1).PasteSpecial xlPasteValues
.Cells(1).Activate
End With
Else
'Format the summary sheet if the user has created separate target sheets
ws1.Activate
ws1.Range("A1:B1").Font.Bold = True
ws1.Columns.AutoFit
End If
With Application
.CutCopyMode = False
.DisplayAlerts = True
.EnableEvents = True
.ScreenUpdating = True
.Calculation = lngCalc
.StatusBar = vbNullString
End With
End Sub
Function BrowseForFolder(Optional OpenAt As Variant) As Variant
'From Ken Puls as used in his vbaexpress.com article
'http://www.vbaexpress.com/kb/getarticle.php?kb_id=284
Dim ShellApp As Object
'Create a file browser window at the default folder
Set ShellApp = CreateObject("Shell.Application"). _
BrowseForFolder(0, "Please choose a folder", 0, OpenAt)
'Set the folder to that selected. (On error in case cancelled)
On Error Resume Next
BrowseForFolder = ShellApp.self.Path
On Error GoTo 0
'Destroy the Shell Application
Set ShellApp = Nothing
'Check for invalid or non-entries and send to the Invalid error
'handler if found
'Valid selections can begin L: (where L is a letter) or
'\\ (as in \\servername\sharename. All others are invalid
Select Case Mid(BrowseForFolder, 2, 1)
Case Is = ":"
If Left(BrowseForFolder, 1) = ":" Then GoTo Invalid
Case Is = "\"
If Not Left(BrowseForFolder, 1) = "\" Then GoTo Invalid
Case Else
GoTo Invalid
End Select
Exit Function
Invalid:
'If it was determined that the selection was invalid, set to False
BrowseForFolder = False
End Function
You should show us some code if you really want help.
But as far as I understood your question, here are some tips or links.
Code snippet to loop over worksheets
Dim wkbkorigin As Workbook
Dim ws As Worksheet
Set wkbkorigin = Workbooks.Open("C:\bookB.xls")
For Each ws In wkbkorigin.Worksheets
'do whatever
Next
Some stackoverflow threads about this issue
excel vba loop through worksheets and set values according to input
How can I loop through a subset of worksheets?
Some more tips about getting info from files
See this valuable thread: Copy data from another Workbook through VBA
You will find info about:
how to use the Excel object model to copy data from a file to another
using GetInfoFromClosedFile() function
Once you've defined workbooks/worksheets as per JMax response, I think you're looking for the following...
IncludeSheet=0
For n = 1 to wkbkOrigin.Worksheets.Count
If wkbkOrigin.Sheets(n).Name = "End" Then
IncludeSheet = 0
End If
If IncludeSheet = 1 Then
Set ws = wkbkOrigin.Sheets(n)
'do whatever
End If
If wkbkOrigin.Sheets(n).Name = "Start" Then
IncludeSheet = 1
End If
Next n
The key is to introduce a flag variable to tell you if you're in the right part of the workbook, in this case IncludeSheet