Extract text from column D to txt files and name files based on content of column C - vba

Apologies for a noob question but I've been fiddling around with this code:
https://stackoverflow.com/a/7151963/3672159
and can't seem to get it modified to do the following (very slight modifications of the code above):
Take as input a worksheet that is called "Export Data" (rather than "Sheet1" as in the existing code; the space seems to cause problems)
Automatically create an empty file for each cell of column D, which should have as its content the value of the respective D cell (same as with the "Disclaimer" data in the code above)
Name each file based on the values of the corresponding C cells (so for me it's name=column C, content=column D rather than B and A in the original code).
I've modified the code as follows:
Sub ExportFiles()
Dim sExportFolder, sFN
Dim rStoreId As Range
Dim rAbstract As Range
Dim oSh As Worksheet
Dim oFS As Object
Dim oTxt As Object
'sExportFolder = path to the folder you want to export to
'oSh = The sheet where your data is stored
sExportFolder = "my file path\txt"
Set oSh = Export Data
Set oFS = CreateObject("Scripting.Filesystemobject")
For Each rStoreId In oSh.UsedRange.Columns("D").Cells
Set rAbstract = rStoreId.Offset(, -1)
'Add .txt to the article name as a file name
sFN = rStoreId.Value & ".txt"
Set oTxt = oFS.OpenTextFile(sExportFolder & "\" & sFN, 2, True)
oTxt.Write rAbstract.Value
oTxt.Close
Next
End Sub
The only thing this does (as does the original code) is create one empty unnamed txt file.
Any help is greatly appreciated!

Try this...
Sub ExportFiles()
Dim sExportFolder, sFN
Dim rStoreId As Range
Dim rAbstract As Range
Dim oSh As Worksheet
Dim oFS As Object
Dim oTxt As Object
'sExportFolder = path to the folder you want to export to
'oSh = The sheet where your data is stored
sExportFolder = "C:\Users\Rich\Desktop"
Set oSh = ThisWorkbook.Sheets("Export Data")
Set oFS = CreateObject("Scripting.Filesystemobject")
For Each rStoreId In oSh.Columns("D").Cells
If IsEmpty(rStoreId.Value) Then
Exit For
End If
Set rAbstract = rStoreId.Offset(, -1)
'Add .txt to the article name as a file name
sFN = rStoreId.Value & ".txt"
Set oTxt = oFS.OpenTextFile(sExportFolder & "\" & sFN, 2, True)
oTxt.Write rAbstract.Value
oTxt.Close
Next
End Sub
You need to select the sheet correctly with (Assuming it is within the same workbook as the code)...
Set oSh = ThisWorkbook.Sheets("Export Data")
And I changed how you were iterating through the range...
For Each rStoreId In oSh.Columns("D").Cells
If IsEmpty(rStoreId.Value) Then
Exit For
End If
Next
This just goes through column D's cells until it hits an empty one, I couldn't quite get it working using UsedRange and this (more old skool) method works in my tests.

This works for me. It writes each value in cells in column D to a text file that is named based on the entry in column C and puts all text files in user specified folder:
Sub ExportFiles()
Dim exportFolder As String
Dim fso As FileSystemObject
Dim stream As TextStream
Dim cl As Range
exportFolder = "C:\User\ExportFolder" //Add you folder path here
Set fso = New FileSystemObject
For Each cl In Worksheets("Export Data").UsedRange.Columns("D").Cells
Set stream = fso.CreateTextFile(filepath & "\" & cl.Offset(0, -1).Value & ".txt", 2, True)
stream.Write cl.Value
stream.Close
Next
End Sub

Related

How to remove extra empty text file created using vba excel macro wherein its filename is the cell in a sheet?

I'm just new in using excel vba macro. I am trying to create text file and use the cell values as name of individual text file. At the first place the value contains character and those character will be replaced. the only value will remain are all numbers. That function is working well. My problem is once I execute the create button, the program will create an extra text file which name is base on empty cell and no any input "D" as input in the text file. What I want is to create a text file without that extra text file created. below is my excel format and the code.
I have 3 column use as below:
LOG DATA INPUT BLOCK NAME
5687 D ASD
5689 D
5690 D
5692 D
5691 D
5688 D
4635 D
Correct result will create four text file:
abc-5687.req
abc-5689.req
abc-5690.req
abc-5692.req
Result with extra text file consider as wrong see below:
abc-.req <-- extra text file created
abc-5687.req
abc-5689.req
abc-5690.req
abc-5692.req
my code:
Private Sub CREATE_REQ_Click()
Dim myDataSheet As Worksheet
Dim myReplaceSheet As Worksheet
Dim myLastRow As Long
Dim myRow As Long
Dim myFind As String
Dim myReplace1 As String
Dim myReplace2 As String
Dim sExportFolder, sFN
Dim rArticleName As Range
Dim rDisclaimer As Range
Dim oSh As Worksheet
Dim oFS As Object
Dim oTxt As Object
' Specify name of Data sheet
Set myDataSheet = Sheets("Sheet1")
' Specify name of Sheet with list of replacements
Set myReplaceSheet = Sheets("Sheet2")
' Assuming list of replacement start in column A on row 2, find last entry in list
myLastRow = myReplaceSheet.Cells(Rows.Count, "A").End(xlUp).Row
Application.ScreenUpdating = False
' Loop through all list of replacments
For myRow = 2 To myLastRow
' Get find and replace values (from columns A and B)
myFind = myReplaceSheet.Cells(myRow, "A")
myReplace1 = myReplaceSheet.Cells(myRow, "B")
' Start at top of data sheet and do replacements
myDataSheet.Activate
Range("A2").Select
' Ignore errors that result from finding no matches
On Error Resume Next
' Do all replacements on column A of data sheet
Columns("A:A").Replace What:=myFind, Replacement:=myReplace1, LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
Next myRow
sExportFolder = "D:\TEST\REQ_FILES_CREATED_HERE"
Set oSh = Sheet1
Set oFS = CreateObject("Scripting.Filesystemobject")
For Each rArticleName In oSh.UsedRange.Columns("A").Cells
Set rDisclaimer = rArticleName.Offset(, 1)
If rArticleName = "" & "LOG DATA" Then
oTxt = False
Else
'Add .txt to the article name as a file name
sFN = "-" & rArticleName.Value & ".req"
Set oTxt = oFS.OpenTextFile(sExportFolder & "\" & ActiveSheet.Cells(2, 3) & sFN, 2, True)
oTxt.Write rDisclaimer.Value
oTxt.Close
End If
Next
'Reset error checking
On Error GoTo 0
Application.ScreenUpdating = True
MsgBox "Replacements complete! "
End Sub
For Each rArticleName In oSh.UsedRange.Columns("A").Cells
Set rDisclaimer = rArticleName.Offset(, 1)
If Not(rArticleName = "" Or rArticleName = "LOG DATA") Then
'Add .txt to the article name as a file name
sFN = "-" & rArticleName.Value & ".req"
Set oTxt = oFS.OpenTextFile(sExportFolder & "\" & ActiveSheet.Cells(2, 3) & sFN, 2, True)
oTxt.Write rDisclaimer.Value
oTxt.Close
End If
Next
Pretty close to a one line fix. You just need to fix the If. Once that's right you don't need the Else.

copy paste from one file to several files

I would like to copy some cells from one file to several files. In order to do so,the macro will copy the range and open the several files in order to paste the values. I perform a loop in order to open each of the destination files (the begin of the name of each of the ouput file is the same but the extension differs from file to file : it is based on a range of cells called Name). The concatenation doesn't work well.
Thank you so much for your help!!
Sub update()
Application.ScreenUpdating = False
Dim wkbkorigin As Workbook
Dim wkbkdestination As Workbook
Dim originsheet As Worksheet
Dim destsheet As Worksheet
Dim i As Integer
Dim j As Integer
Dim nrow As Integer
Dim ncol As Integer
Dim Pathref As String
Dim Name As String
nrow = Range("names").Rows.Count
ncol = Range("Range").Columns.Count
'this is the path to the different files, the begin is the same but the extension will be added in the loop (the extentsion is based on the value in the range Name
Pathref = Range("Pathref").Value & "[yasmine_nouri]"
For i = 1 To nrow
Name = Range("Names").Cells(i, 1).Value
Set wkbkorigin = ActiveWorkbook
'here i set my destination file, the begin is the same but the extension is based on the value in the range Name : this concatenation doesn't work.
Set wkbkdestination = Workbooks.Open([& Pathref & Name & ".xlsb"])
Set originsheet = wkbkorigin.Worksheets("Completed_DS")
Set destsheet = wkbkdestination.Worksheets("sheet1")
originsheet.Range("D4:Q5").Copy
destsheet.Range("A1").PasteSpecial
wkbkdestination.Close SaveChanges:=True
Next i
End Sub
As follows up from comments, OP should change
Pathref = Range("Pathref").Value & "[yasmine_nouri]"
'...
Set wkbkdestination = Workbooks.Open([& Pathref & Name & ".xlsb"])
to
Pathref = Range("Pathref").Value & "yasmine_nouri"
'...
Set wkbkdestination = Workbooks.Open(Pathref & Name & ".xlsb")

mulitiple files to extract a similar word table from each to excel VBA

I have in excess of 300 word documents that include word tables, and I have been trying to write a VBA script for excel to extract the information I need, and I am completely new to Visual Basic. I need to copy the file name to the first cell, and the following cells to contain the information I am trying to extract, followed by the next file name, looping on until all word documents have been searched and extracted. I have tried multiple different ways, but the closest code I can find is as follows. It works to pull part numbers, but not descriptions. It also pulls extraneous information that doesn't need to be there, but I can work around that information if it is a necessary hazard.
I have an example word file (replaced sensitive information with other information), but I am not sure how to attach the word document or jpegs of page 1 and 2 of the word document. I know it would be beneficial if you could see it, so please let me know how to get it on here or to you so you can see it.
So to re-iterate:
I need the file name in the first cell (A1)
I need a certain cell out of table 3 from a word document to excel
If at all possible, I need descriptions in column B (B2:B?) and
mixture of letters and numbers in column C (C2:C?), then on the next
line down, the next file name (A?), and continue to repeat. If you
have any ideas, or suggestions, please let me know. And if I can't
post the picture, or the actual sample document, I am willing to
email, or any other means necessary to get help on this.
Here is the code I have been trying to manipulate. I found it and it was for a first and last row of a form, and I tried to get it to work, for my purposes to no avail:
Sub GetTablesFromWord()
'this Excel file must be in
'the same folder with the Word
'document files that are to be'processed.
Dim wApp As Word.Application
Dim wDoc As Word.Document
Dim wTable As Word.Table
Dim wCell As Word.Cell
Dim basicPath As String
Dim fName As String
Dim myWS As Worksheet
Dim xlCell As Range
Dim lastRow As Long
Dim rCount As Long
Dim cCount As Long
Dim RLC As Long
Dim CLC As Long
basicPath = ThisWorkbook.Path & Application.PathSeparator
'change the sheet name as required
Set myWS = ThisWorkbook.Worksheets("Sheet1")
'clear any/all previous data on the sheet myWS.Cells.Clear
'"open" Word Set wApp = CreateObject("Word.Application")
'get first .doc file name in the folder
'with this Excel file
fName = Dir(basicPath & "*.doc*")
Do While fName <> ""
'this puts the filename into column A to
'help separate the table data in Excel
myWS.Range("A" & Rows.Count).End(xlUp).Offset(1, 0) = _
"FILE: [" & fName & "]"
'open the Word file
wApp.Documents.Open basicPath & fName
Set wDoc = wApp.Documents(1)
'if there is a table in the
'Word Document, work with it
If wDoc.Tables.Count > 0 Then
Set wTable = wDoc.Tables(3)
rCount = wTable.Rows.Count
cCount = wTable.Columns.Count
For RLC = 1 To rCount
lastRow = myWS.Range("A" & Rows.Count).End(xlUp).Row + 1
For CLC = 1 To cCount
'if there are merged cells in the
'Word table, an error will be
'generated - ignore the error,
'but also won't process the data
On Error Resume Next
Set wCell = wTable.Cell(RLC, CLC)
If Err <> 0 Then
Err.Clear
Else
If CLC = 1 Then
Set xlCell = myWS.Range("A" & lastRow)
xlCell = wCell
Else
Set xlCell = myWS.Range("B" & lastRow)
xlCell = wCell
End If
End If
On Error GoTo 0
Next
Next
Set wCell = Nothing
Set wTable = Nothing
End If ' end of wDoc.Tables.Count test
wDoc.Close False
Set wDoc = Nothing
fName = Dir()
' gets next .doc* filename in the folder
Loop wApp.Quit
Set wApp = Nothing
MsgBox "Task Completed"
End Sub
This code loops through all of the .docx files contained within a folder, extracts data into your spreadsheet, closes the word document, and moves onto the next document. The name of the word document gets extracted into Column A, and a value from within the 3rd table in the document is extracted into Column B. This should be a good starting point for you to build upon.
Sub wordScrape()
Dim wrdDoc As Object, objFiles As Object, fso As Object, wordApp As Object
Dim sh1 As Worksheet
Dim x As Integer
FolderName = "C:\code" ' Change this to the folder containing your word documents
Set sh1 = ThisWorkbook.Sheets(1)
Set fso = CreateObject("Scripting.FileSystemObject")
Set wordApp = CreateObject("Word.application")
Set objFiles = fso.GetFolder(FolderName).Files
x = 1
For Each wd In objFiles
If InStr(wd, ".docx") And InStr(wd, "~") = 0 Then
Set wrdDoc = wordApp.Documents.Open(wd.Path, ReadOnly = True)
sh1.Cells(x, 1) = wd.Name
sh1.Cells(x, 2) = Application.WorksheetFunction.Clean(wrdDoc.Tables(3).Cell(Row:=3, Column:=2).Range)
'sh1.Cells(x, 3) = ....more extracted data....
x = x + 1
wrdDoc.Close
End If
Next wd
wordApp.Quit
End Sub

How do I get the timestamp of a specific file over multiple files within the same folder?

I'm trying to write a simple script that looks into a folder, finds the specified file, then spits out the timestamp on a cell. That is the easy part which I already have, (using a string & object).
The part where I'm having issues is having this repeat over 400 specific files within a folder of +1,000 files. All the files are labeled differently, but some may have similarities (AB.xls, AC.xls, AD.xls ; A1.xls, A2.xls, etc). I could go the long way and just rinse and repeat just changing the string name to each specific file, but that would take too long to write.
Is there a short cut to loop this or would I need to add a variable line for the file name to change each time?
Here is a snippet:
Sub Timecheck()
Dim oFS As Object
Dim strFilename As String
strFilename = "Where the file is located"
Set oFS = CreateObject("Scripting.FileSystemObject")
Sheets("tab").Activate
ActiveSheet.Cells(3, 3).Value = oFS.GetFile(strFilename).Datelastmodified
Set oFS = Nothing
End Sub
If the names of the files are on another sheet you need to create another function that will iterate through that range of cells.
Once you have that function in place have it call this function:
Sub Timecheck(byval aCell as object,byval X as integer,Y as integer)
Dim oFS As Object
Dim strFilename As String
strFilename = aCell.Text
Set oFS = CreateObject("Scripting.FileSystemObject")
Sheets("tab").Activate
ActiveSheet.Cells(X,Y).Value = oFS.GetFile(strFilename).Datelastmodified
Set oFS = Nothing
End Sub
where X and Y are the coordinates of the cell you want to put the data in. You call it by passing in the cell in the range that you have grabbed from the other sheet.
Alternately if you do not want to have to traverse a range then put each file name in a single cell on the new sheet and delimit it with a character that won't show up in the name. Then take that and break it into the file names.
Good luck.
EDIT:
If you wanted to iterate through the items in a delimited list inside a cell, then once you have the cell text in an object:
http://msdn.microsoft.com/en-us/library/6x627e5f(v=vs.80).aspx
with an input of 'filename1.xls^filename2.xls^filename3.xls'
call once you have the cell object that contains the file list
DoStuff(cellObejct, "^")
Public Sub DoStuff( byval aCell as object, byval specialChar as string)
Dim ListOfNames as Variant
Dim intIndex, xCell, yCell as integer
ListOfNames = Split(aCell.Text,specialChar)
xCell = 1
yCell = 1
For intIndex = LBound(ListOfNames) To UBound(ListOfNames)
TimeCheck(ListOfNames(intIndex),xCell,yCell)
yCell = yCell + 1
Next intIndex
End Sub
Sub Timecheck(byval fName as string,byval X as integer,Y as integer)
Dim oFS As Object
Set oFS = CreateObject("Scripting.FileSystemObject")
Sheets("tab").Activate
ActiveSheet.Cells(X,Y).Value = oFS.GetFile(fName).Datelastmodified
Set oFS = Nothing
End Sub
To loop thought a folder:
Sub timecheck()
Dim FSO As Object
Dim FLD As Object
Dim fil As Object
Dim i As Long
Dim strFolder As String
i = 1
strFolder = "C:\Your Folder Name"
'Create the filesystem object
Set FSO = CreateObject("Scripting.FileSystemObject")
'Get a reference to the folder you want to search
Set FLD = FSO.GetFolder(strFolder)
'loop through the folder and get the file names
For Each fil In FLD.Files
Sheets("Sheet1").Cells(i, 1) = fil.Name ' Filename in column A
Sheets("Sheet1").Cells(i, 2) = fil.datelastmodified ' Date in column B
i = i + 1
Next
End Sub

How to copy data from another workbook (excel)?

I already have a macro that creates sheets and some other stuff. After a sheet has been created do I want to call another macro that copies data from a second excel (its open) to first and active excel file.
First I want to copy to headers, but I cant get that to work - keep getting errors.
Sub CopyData(sheetName as String)
Dim File as String, SheetData as String
File = "my file.xls"
SheetData = "name of sheet where data is"
# Copy headers to sheetName in main file
Workbooks(File).Worksheets(SheetData).Range("A1").Select # fails here: Method Select for class Range failed
Workbooks(File).Worksheets(SheetData).Range(Selection, Selection.End(xlToRight)).Select
Workbooks(File).Worksheets(SheetData).Selection.Copy ActiveWorkbook.Sheets(sheetName).Cells(1, 1)
End Sub
What is wrong ?
I really want to avoid having to make "my file.xls" active.
Edit: I had to give it up and copy the SheetData to target file as a new sheet, before it could work.
Find and select multiple rows
Two years later (Found this on Google, so for anyone else)... As has been mentioned above, you don't need to select anything. These three lines:
Workbooks(File).Worksheets(SheetData).Range("A1").Select
Workbooks(File).Worksheets(SheetData).Range(Selection, Selection.End(xlToRight)).Select
Workbooks(File).Worksheets(SheetData).Selection.Copy ActiveWorkbook.Sheets(sheetName).Cells(1, 1)
Can be replaced with
Workbooks(File).Worksheets(SheetData).Range(Workbooks(File).Worksheets(SheetData). _
Range("A1"), Workbooks(File).Worksheets(SheetData).Range("A1").End(xlToRight)).Copy _
Destination:=ActiveWorkbook.Sheets(sheetName).Cells(1, 1)
This should get around the select error.
Best practice is to open the source file (with a false visible status if you don't want to be bother) read your data and then we close it.
A working and clean code is avalaible on the link below :
http://vba-useful.blogspot.fr/2013/12/how-do-i-retrieve-data-from-another.html
Would you be happy to make "my file.xls" active if it didn't affect the screen? Turning off screen updating is the way to achieve this, it also has performance improvements (significant if you are doing looping while switching around worksheets / workbooks).
The command to do this is:
Application.ScreenUpdating = False
Don't forget to turn it back to True when your macros is finished.
I don't think you need to select anything at all. I opened two blank workbooks Book1 and Book2, put the value "A" in Range("A1") of Sheet1 in Book2, and submitted the following code in the immediate window -
Workbooks(2).Worksheets(1).Range("A1").Copy Workbooks(1).Worksheets(1).Range("A1")
The Range("A1") in Sheet1 of Book1 now contains "A".
Also, given the fact that in your code you are trying to copy from the ActiveWorkbook to "myfile.xls", the order seems to be reversed as the Copy method should be applied to a range in the ActiveWorkbook, and the destination (argument to the Copy function) should be the appropriate range in "myfile.xls".
I was in need of copying the data from one workbook to another using VBA. The requirement was as mentioned below 1. On pressing an Active X button open the dialogue to select the file from which the data needs to be copied. 2. On clicking OK the value should get copied from a cell / range to currently working workbook.
I did not want to use the open function because it opens the workbook which will be annoying
Below is the code that I wrote in the VBA. Any improvement or new alternative is welcome.
Code: Here I am copying the A1:C4 content from a workbook to the A1:C4 of current workbook
Private Sub CommandButton1_Click()
Dim BackUp As String
Dim cellCollection As New Collection
Dim strSourceSheetName As String
Dim strDestinationSheetName As String
strSourceSheetName = "Sheet1" 'Mention the Source Sheet Name of Source Workbook
strDestinationSheetName = "Sheet2" 'Mention the Destination Sheet Name of Destination Workbook
Set cellCollection = GetCellsFromRange("A1:C4") 'Mention the Range you want to copy data from Source Workbook
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
.Show
'.Filters.Add "Macro Enabled Xl", "*.xlsm;", 1
For intWorkBookCount = 1 To .SelectedItems.Count
Dim strWorkBookName As String
strWorkBookName = .SelectedItems(intWorkBookCount)
For cellCount = 1 To cellCollection.Count
On Error GoTo ErrorHandler
BackUp = Sheets(strDestinationSheetName).Range(cellCollection.Item(cellCount))
Sheets(strDestinationSheetName).Range(cellCollection.Item(cellCount)) = GetData(strWorkBookName, strSourceSheetName, cellCollection.Item(cellCount))
Dim strTempValue As String
strTempValue = Sheets(strDestinationSheetName).Range(cellCollection.Item(cellCount)).Value
If (strTempValue = "0") Then
strTempValue = BackUp
End If
Sheets(strDestinationSheetName).Range(cellCollection.Item(cellCount)) = strTempValue
ErrorHandler:
If (Err.Number <> 0) Then
Sheets(strDestinationSheetName).Range(cellCollection.Item(cellCount)) = BackUp
Exit For
End If
Next cellCount
Next intWorkBookCount
End With
End Sub
Function GetCellsFromRange(RangeInScope As String) As Collection
Dim startCell As String
Dim endCell As String
Dim intStartColumn As Integer
Dim intEndColumn As Integer
Dim intStartRow As Integer
Dim intEndRow As Integer
Dim coll As New Collection
startCell = Left(RangeInScope, InStr(RangeInScope, ":") - 1)
endCell = Right(RangeInScope, Len(RangeInScope) - InStr(RangeInScope, ":"))
intStartColumn = Range(startCell).Column
intEndColumn = Range(endCell).Column
intStartRow = Range(startCell).Row
intEndRow = Range(endCell).Row
For lngColumnCount = intStartColumn To intEndColumn
For lngRowCount = intStartRow To intEndRow
coll.Add (Cells(lngRowCount, lngColumnCount).Address(RowAbsolute:=False, ColumnAbsolute:=False))
Next lngRowCount
Next lngColumnCount
Set GetCellsFromRange = coll
End Function
Function GetData(FileFullPath As String, SheetName As String, CellInScope As String) As String
Dim Path As String
Dim FileName As String
Dim strFinalValue As String
Dim doesSheetExist As Boolean
Path = FileFullPath
Path = StrReverse(Path)
FileName = StrReverse(Left(Path, InStr(Path, "\") - 1))
Path = StrReverse(Right(Path, Len(Path) - InStr(Path, "\") + 1))
strFinalValue = "='" & Path & "[" & FileName & "]" & SheetName & "'!" & CellInScope
GetData = strFinalValue
End Function