I have a list of unique ID's in a spreadsheet and each (but not all) of the IDs has a single related spreadsheet, all stored in the same location. I need to extract a number from each xlsx. file (in the same cell in each file) and match it to the list of unique IDs. All the files have the same naming convention of 'UniqueID_Otherinformation.xlxs' All unique IDs are 6 figures.
Sub OpenFile()
Dim sPath As String
Dim sFil As String
Dim strName As String
Dim twbk As Workbook
Dim owbk As Workbook
Dim ws As Worksheet
Set twbk = ActiveWorkbook
sPath = "C:\Data Folder\"
sFil = Dir(sPath & "*.xls")
Do While sFil <> ""
strName = sPath & sFil
Set owbk = Workbooks.Open(strName)
Set ws = owbk.Sheets(1)
ws.Range("A1", Range("A" & Row.Count).End(xlUp)).Copy
twbk.Sheets(1).Range("A65536").End(xlUp)(2).PasteSpecial xlPasteValues
owbk.Close False
sFil = Dir
Loop
twbk.Save
End Sub
I made a start but got very lost very quickly.
Edit: Apologies, not clear about my needs. I'm not sure how to solve the problem. I made a start with code above but it is not very close to what I am intending so am hoping for your expertise here as I am unsure how to proceed.
Worksheets("Source").Columns("A:D").Copy Destination:=Worksheets("Target").Range("a1")
Have a look at the above. This code moves from the first sheet to the second. No need to copy+paste, and much simpler method
Apply it to your code as needed
Related
I import sheets into a file, then save the file with a new name in a different location.
The macro works until the memory usage for Excel reaches about 3,000MB, at which point an "Out of Memory" error occurs. (There is 32GB of memory on this PC.)
The error occurs on this line, Set Wkb3 = Workbooks.Open(filename:=Path & "\" & filename) presumably because there isn't enough memory to open another file.
Wkb3, which is the source file where the sheet is being imported from, is closed after the import.
Wkb2, which contains the collection of imported sheets is saved and closed after the imports are done.
Wkb1 is the only one that is constantly open.
I usually manage to go through 40 or so iterations before the crash, so clearly even though all Wkb2 and Wkb3 are being closed, something is staying in Excel's memory.
I tried saving Wkb2 after each import to see if that will release memory.
I tried setting Objects to nothing.
Here's my macro:
Option Explicit
Sub CombineFiles()
Call NewBook 'this marco creates a new file that will hold the imported sheets
Dim Wkb1 As Workbook 'Wkb with Macro
Set Wkb1 = ThisWorkbook
Dim Aname As String
Aname = Wkb1.Sheets(1).Range("A1").Value & "\Master File\Master File.xlsx" 'cell A1 holds the path for each individual folder that holds files that need to be combined
Dim Wkb2 As Workbook 'MasterBook
Set Wkb2 = Workbooks.Open(filename:=Aname)
Dim Wkb3 As Workbook 'DataSource
Dim ws1 As Worksheet 'Wkb with Macro
Set ws1 = Wkb1.Worksheets(1)
Dim ws3 As Worksheet 'DataSource
Dim MyOldName As String
MyOldName = Wkb2.FullName
Dim Path As String
Path = ws1.Range("A1").Value
Dim filename As String
filename = Dir(Path & "\*.xlsx", vbNormal)
Dim Path2 As String
Dim filename2 As String
Path2 = Path & "\Master File\"
Do Until filename = ""
Set Wkb3 = Workbooks.Open(filename:=Path & "\" & filename)
For Each ws3 In Wkb3.Worksheets
ws3.Copy after:=Wkb2.Sheets(Wkb2.Sheets.Count)
Next ws3
Wkb3.Close False
filename = Dir()
Loop
Application.DisplayAlerts = False
filename2 = Wkb2.Worksheets(2).Range("A2").Text
Wkb2.SaveAs filename:=Path & filename & ".xlsx"
Wkb2.Close True
Kill MyOldName
Call KillFiles
Application.DisplayAlerts = True
End Sub
Unfortunately, the only fix I was able to come up with was to Kill excel and restart the Macro via the Windows Task Scheduler. It doesn't fix the "out of memory" error, but at least it restarts the Macro every now and then so I don't lose time on it being stuck on this error.
If you are running Exce32 bits, the limit is 4Gb.
I have written a code that opens a password protected workbook in a folder, copy some values out of it and paste the values in active woorkbook. This works fine.
My problem is that I have 16 password protected files in this folder, and I need a loop that does the same thing with every file. Below you can find the code, and I think all my problems should be properly explained with comments inside the code. Please ask if anything is unclear. In advance, thanks for any help!
Code:
Sub Bengt()
Dim sPath As String
Dim vFolder As Variant
Dim sFile As String
Dim sDataRange As String
Dim mydata As String
Dim wb As Workbook
Dim WBookOther As Workbook
Dim myArray As Variant '<<does the list of passwords have to be array?
sPath = ThisWorkbook.Path & Application.PathSeparator
sDataRange = "Budsjett_resultat'!E2" '<<every file I want to open has data in this sheet and range
sFile = "BENGT.xlsm" '<< how to make sFile be every file in folder?
' here I want a loop that opens every woorkbook in the folder M::\SALG\2016\Budsjett\
Set WBookOther = Workbooks.Open(sPath & sFile, Password:="bengt123")
' all passwords starts with filename + three numbers after as you can see
' here I want to make excel find the password out of a list of passwords in range B100:B116
mydata = "='" & sPath & "[" & sFile & "]" & sDataRange
'mydata = "='M:\SALG\2016\Budsjett\Bengt.xlsmBudsjett_resultat'!E2:E54" '<< change as required
'link to worksheet
With ThisWorkbook.Worksheets(1).Range("T2:T54")
'in this case I want the loop to find "BENGT"(which is the filename) in cell T1, and paste the values in range T2:T54.
'For the other files, I want the loop to find the filename (of the file it opened) in row 1,
'and paste the values in range ?2-?54 at the column with the same name as the filename
.Formula = mydata
.Value = .Value
WBookOther.Close SaveChanges:=False
End With
End Sub
For the password array I have tried following code:
Sub passord()
Dim myArray As Variant
myArray = ThisWorkbook.Worksheets(1).Range("B100:B116")
On Error Resume Next 'turn error reporting off
For i = LBound(myArray, 1) To UBound(myArray, 1)
Set wb = Workbooks.Open("M:\SALG\2016\Budsjett\BENGT.xlsm", Password:=myArray(i, 1))
If Not wb Is Nothing Then bOpen = True: Exit For
Next i
End Sub
I have tried to implement the last sub into the first sub, but I can't figure out how to make it work.
I am creating a function that reads column titles from two excel files and then place those column titles in checkboxes so the user can check which columns he will work with. It works when I do it with one file but when I modify it to work with two files I get the "run time error 9: Subscript out of range" and highlights the line => Set wks2 = ActiveWorkbook.Worksheets(SheetName2).
Even with this error message still works for the first file but it does not work with the second file. Can anybody help me to find the reason of this error message? Thank you very much in advance.
Function CallFunction(SheetName1 As Variant, SheetName2 As Variant) As Long
' This is a function used to retrieve column titles and place them as checkboxes in a listBox
Dim jTitles(200) As String
Dim sTitles(200) As String
Dim titless As Integer
Dim titlesj As Integer
Dim wks1 As Worksheet
Dim wks2 As Worksheet
Dim Item(200) As String
SPathName = Range("F18").Value
SFilename = Range("F19").Value
JPathName = Range("F22").Value
JFilename = Range("F23").Value
Workbooks.Open Filename:=SPathName & "\" & SFilename
Workbooks.Open Filename:=JPathName & "\" & JFilename
Set wks1 = ActiveWorkbook.Worksheets(SheetName1)
For j = 1 To 199
If Trim(wks1.Cells(4, j).Value) = "" Then
titlesj = j - 1
Exit For
End If
jTitles(j - 1) = wks1.Cells(4, j).Value
Next
j = 1
' Add column titles from files into the listbox as checkboxes
For j = 0 To titlesj
Sheet1.ListBox1.AddItem jTitles(j)
Sheet1.ListBox3.AddItem jTitles(j)
Next
Set wks2 = ActiveWorkbook.Worksheets(SheetName2) ' <=== HERE POPS THE ERROR MESSAGE
For s = 1 To 199
If Trim(wks2.Cells(1, s).Value) = "" Then
titless = s - 1
Exit For
End If
sTitles(s - 1) = wks2.Cells(1, j).Value
Next
s = 1
For s = 0 To titless
Sheet1.ListBox2.AddItem sTitles(s)
Sheet1.ListBox4.AddItem sTitles(s)
Next
Workbooks(JFilename).Close
' Workbooks(SFilename).Close
End Function
Subscript out of Range error arises in these circumstances when the specified sheetname does not exist in that workbooks Worksheets collection.
I notice you have two open workbooks specified by:
Workbooks.Open Filename:=SPathName & "\" & SFilename
Workbooks.Open Filename:=JPathName & "\" & JFilename
However, both of your worksheet assignments refer only to the ActiveWorkbook.
The cause of the error is certainly that SheetName2 does not exist in the ActiveWorkbok (which is specified by JFilename)
Especially when working with multiple books or worksheets, it is always preferable to avoid using Activate/Select methods-- otherwise you need to keep track of which workbook/worksheet/etc. is "Active", and that makes for spaghetti code and lots of unnecessary calls to the .Activate method.
I know that SheetName1 exists in JFilename, and I am assuming that SheetName2 exist in the workbook SFileName.
Instead, define two Workbook variables:
Dim wb1 as Workbook
Dim wb2 as Workbook
Assign the results of the Workbooks.Open method to these workbooks:
Set wb2 = Workbooks.Open(Filename:=SPathName & "\" & SFilename)
Set wb1 = Workbooks.Open(Filename:=JPathName & "\" & JFilename)
Now, wb1 is the "Active" workbook, so with the worksheet assignments:
Set wks1 = wb1.Worksheets(SheetName1)
And later for the Sheetname2:
Set wks2 = wb2.Worksheets(Sheetname2)
Otherwise, there is a typo in your worksheet names or the string parameters you're sending to this function. Doublecheck/debug that the value of SheetName2 is correct and that it exists.
I want to collect data from different files and insert it into a workbook doing something like this.
Do While THAT_DIFFERENT_FILE_SOMEWHERE_ON_MY_HDD.Cells(Rand, 1).Value <> "" And Rand < 65536
then 'I will search if the last row in my main worksheet is in this file...
End Loop
If the last row from my main worksheet is in the file, I'll quit the While Loop. If not, I'll copy everything. I'm having trouble finding the right algorithm for this.
My problem is that I don't know how to access different workbooks.
The best (and easiest) way to copy data from a workbook to another is to use the object model of Excel.
Option Explicit
Sub test()
Dim wb As Workbook, wb2 As Workbook
Dim ws As Worksheet
Dim vFile As Variant
'Set source workbook
Set wb = ActiveWorkbook
'Open the target workbook
vFile = Application.GetOpenFilename("Excel-files,*.xls", _
1, "Select One File To Open", , False)
'if the user didn't select a file, exit sub
If TypeName(vFile) = "Boolean" Then Exit Sub
Workbooks.Open vFile
'Set targetworkbook
Set wb2 = ActiveWorkbook
'For instance, copy data from a range in the first workbook to another range in the other workbook
wb2.Worksheets("Sheet2").Range("C3:D4").Value = wb.Worksheets("Sheet1").Range("A1:B2").Value
End Sub
You might like the function GetInfoFromClosedFile()
Edit: Since the above link does not seem to work anymore, I am adding alternate link 1 and alternate link 2 + code:
Private Function GetInfoFromClosedFile(ByVal wbPath As String, _
wbName As String, wsName As String, cellRef As String) As Variant
Dim arg As String
GetInfoFromClosedFile = ""
If Right(wbPath, 1) <> "" Then wbPath = wbPath & ""
If Dir(wbPath & "" & wbName) = "" Then Exit Function
arg = "'" & wbPath & "[" & wbName & "]" & _
wsName & "'!" & Range(cellRef).Address(True, True, xlR1C1)
On Error Resume Next
GetInfoFromClosedFile = ExecuteExcel4Macro(arg)
End Function
Are you looking for the syntax to open them:
Dim wkbk As Workbook
Set wkbk = Workbooks.Open("C:\MyDirectory\mysheet.xlsx")
Then, you can use wkbk.Sheets(1).Range("3:3") (or whatever you need)
There's very little reason not to open multiple workbooks in Excel. Key lines of code are:
Application.EnableEvents = False
Application.ScreenUpdating = False
...then you won't see anything whilst the code runs, and no code will run that is associated with the opening of the second workbook. Then there are...
Application.DisplayAlerts = False
Application.Calculation = xlManual
...so as to stop you getting pop-up messages associated with the content of the second file, and to avoid any slow re-calculations. Ensure you set back to True/xlAutomatic at end of your programming
If opening the second workbook is not going to cause performance issues, you may as well do it. In fact, having the second workbook open will make it very beneficial when attempting to debug your code if some of the secondary files do not conform to the expected format
Here is some expert guidance on using multiple Excel files that gives an overview of the different methods available for referencing data
An extension question would be how to cycle through multiple files contained in the same folder. You can use the Windows folder picker using:
With Application.FileDialog(msoFileDialogFolderPicker)
.Show
If .Selected.Items.Count = 1 the InputFolder = .SelectedItems(1)
End With
FName = VBA.Dir(InputFolder)
Do While FName <> ""
'''Do function here
FName = VBA.Dir()
Loop
Hopefully some of the above will be of use
I had the same question but applying the provided solutions changed the file to write in. Once I selected the new excel file, I was also writing in that file and not in my original file. My solution for this issue is below:
Sub GetData()
Dim excelapp As Application
Dim source As Workbook
Dim srcSH1 As Worksheet
Dim sh As Worksheet
Dim path As String
Dim nmr As Long
Dim i As Long
nmr = 20
Set excelapp = New Application
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = False
.Filters.Add "Excel Files", "*.xlsx; *.xlsm; *.xls; *.xlsb", 1
.Show
path = .SelectedItems.Item(1)
End With
Set source = excelapp.Workbooks.Open(path)
Set srcSH1 = source.Worksheets("Sheet1")
Set sh = Sheets("Sheet1")
For i = 1 To nmr
sh.Cells(i, "A").Value = srcSH1.Cells(i, "A").Value
Next i
End Sub
With excelapp a new application will be called. The with block sets the path for the external file. Finally, I set the external Workbook with source and srcSH1 as a Worksheet within the external sheet.
I have a workbook that I need to open and then copy the data from the first tab, and then paste it to the original workbook in which the script was created from.
The problem I am running into is that the workbook and the first tab will be named the same thing. So if the workbook name is OpenPOs-100255-08292012.xls the tab is going to be OpenPOs-100255-08292012. Next week though the excel sheet is going to be OpenPOs-200211-12495312.xls which means the tab is going to be OpenPOs-200211-12495312.
With the code I am using right now, is there a way to make it work for this kind of situation? I thought about making it so that the "Sheet 1" becomes the tab of the day? I thought about using `wsPOR.Sheets(wsPOR) but I have a feeling that is going to be coming back as an error. Can someone help please?
Sub Update_TNOOR()
Dim wsTNO As Worksheet
Dim wsTND As Worksheet
Dim wsTNA As Worksheet
Dim wbPOR As Workbook 'New Workbook
Dim wbOOR As Workbook 'ThisWorkbook
Dim lastrow As Long, lastrow2 As Long, fstcell As Long
Dim strFile As String, NewFileType As String, filename As String
Set wsTNO = Sheets("Tel-Nexx OOR")
Set wsTND = Sheets("Tel-Nexx Data")
Set wsTNA = Sheets("Tel-Nexx Archive")
Set wbOOR = ThisWorkbook
With Application
.ScreenUpdating = False
.DisplayAlerts = False
.EnableEvents = False
End With
lastrow = wsTND.Range("A" & Rows.Count).End(xlUp).Row + 1
wsTND.Range("A2:P" & lastrow).Delete
strFile = Application.GetOpenFilename()
NewFileType = "Excel Files 2007 (*.xls)"
Set wbPOR = Application.Workbooks.Open(strFile)
lastrow = wbPOR.Sheets("Sheet1").Range("A" & wbPOR.Sheets("Sheet1").Rows.Count).End(xlUp).Row
wbPOR.Sheets("Sheet1").Range("A4:N" & lastrow).Copy wbOOR.Sheets("Tel-Nexx Data").Range("A2")
wbPOR.Save
wbPOR.Close
End Sub
Based on my comment above, your code, from strFile = Application.GetOpenFilename() to wbPOR.Close becomes:
strFile = Application.GetOpenFilename()
NewFileType = "Excel Files 2007 (*.xls)"
Set wbPOR = Application.Workbooks.Open(strFile)
Dim wsPOR As Worksheet
Set wsPOR = wbPOR.Sheets(Replace(wbPOR.Name, ".xls", ""))
lastrow = wsPOR.Range("A" & wsPOR.Rows.Count).End(xlUp).Row
wsPOR.Range("A4:N" & lastrow).Copy wbOOR.Sheets("Tel-Nexx Data").Range("A2")
wbPOR.Save
wbPOR.Close
use the answers from this question, and substitute that into your sheets() reference
using my answer as an example, your wbPOR.Sheets("Sheet1"). would become
wbPOR.Sheets(left(strFile ,instrrev(strFile ,".")-1)).
which would also have the advantage of working with other extensions should you expand to newer excel versions.