How to define an object inside a for loop for excel vba - vba

I want to import data from multiple workbooks, all from the same sheet index (3).
I'm new to vba, and I figured out how to open multiple files up, and also to copy data from one sheet to another sheet in a different workbook for a single file, but I can't seem to figure out how to do that for multiple files.
I highlighted where the error is, it tells me "object doesn't support this property or method"
Could you please help?
Thanks
Sub dataimport()
' Set Vars
Dim ArbinBook As Workbook, DataBook As Workbook
Dim i As Integer, j As Integer
Dim Caption As String
Dim ArbinFile As Variant, DataFile As Variant
' make weak assumption that active workbook is the target
Set DataBook = Application.ActiveWorkbook
' get Arbin workbook
Caption = "Please select an input file"
' To set open destination:
' ChDrive ("E")
' ChDir ("E:\Chapters\chap14")
' With Application
'Set "arbinfile" as variant, the "true" at end makes it into an array
ArbinFile = Application.GetOpenFilename(, , Caption, , True)
'Exit when canceled
If Not IsArray(ArbinFile) Then
MsgBox "No file was selected."
Exit Sub
End If
Dim targetSheet As Worksheet
Set targetSheet = DataBook.Sheets(1)
'Open for every integer i selected in the array "arbinfile"
For i = LBound(ArbinFile) To UBound(ArbinFile)
Set ArbinBook = Workbooks.Open(ArbinFile(i))
targetSheet.Range("A2", "G150").Value = ArbinBook.Sheets(3).Range("A2", "G150").Value
**ERROR at the line above**
Workbooks(DataSheet).Activate 'Reactivate the data book
Worksheets(1).Activate 'Reactivate the data sheet
ActiveWorkbook.Sheets(1).Copy _
after:=ActiveWorkbook.Sheets(1)
Workbooks(ArbinFile(1)).Activate 'Reactivate the arbin book(i)
ArbinBook.Close
Next i
Beep
End Sub

My instinct tells me that ArbinBook.Sheets(3) is a Chart-sheet, not a WorkSheet (or, at least, it is something other than a WorkSheet). It might be hidden as well, but it will still be indexed as (3).
If so, change Sheets(3) to Worksheets(3).
Added: BTW If true, this also demonstrates why using index-numbers is unreliable. If at all possible, refer to a worksheet by its name. (I appreciate that this may not always be possible.)
Added (from comments) There is nothing named DataSheet in your code. Add Option Explicit to the top of your module to indicate all such errors.

Try changing the line Set ArbinBook = Workbooks.Open(ArbinFile(i))
to Set ArbinBook = Workbooks(arbinfile(i))
I could be wrong, but I think it's trying to set your workbook object to become the action of opening another workbook, instead of labeling it as the workboook.

Sub Multiple()
Application.DisplayAlerts = False
Application.EnableEvents = False
Dim exlApp As Excel.Application
Dim exlWb1 As Excel.Workbook
Dim exlWb2 As Excel.Workbook
Dim exlWb3 As Excel.Workbook
Dim exlWs1 As Excel.Worksheet
Dim exlWs2 As Excel.Worksheet
Dim exlWs3 As Excel.Worksheet
Set exlApp = CreateObject("Excel.Application")
Set exlWb1 = exlApp.Workbooks.Open("C:\yourpath1\file1.xls")
Set exlWb2 = exlApp.Workbooks.Open("C:\yourpath2\file2.xls")
Set exlWb3 = exlApp.Workbooks.Open("C:\yourpath3\file3.xls")
Set exlWs1 = exlWb.Sheets("Sheet1")
Set exlWs2 = exlWb.Sheets("Sheet1")
Set exlWs3 = exlWb.Sheets("Sheet1")
exlWb1.Activate
exlWb2.Activate
exlWb3.Activate
'code
exlWb.Close savechanges:=True
exlWb.Close savechanges:=True
exlWb.Close savechanges:=True
Set exlWs1 = Nothing
Set exlWs2 = Nothing
Set exlWs3 = Nothing
Set exlWb1 = Nothing
Set exlWb2 = Nothing
Set exlWb3 = Nothing
exlApp.Quit
Set exlApp = Nothing
Application.EnableEvents = True
Application.DisplayAlerts = True
End Sub

Related

VBA can't recognize my already open workbook

It says Subscript is out of range. The workbook is already open. I have tried with a path ex:Set wkb2 = Workbooks("d:/A.xlms"). Also I have tried this Set wkb2 = Workbooks.open("d:/A.xlms") with workbook not open. It all returns error mentioning that the file doesn't exist.
Sub CopySourceToTarget()
Dim wkb1 As Workbook
Dim sht1 As Worksheet
Dim wkb2 As Workbook
Dim sht2 As Worksheet
Application.ScreenUpdating = False
Workbooks("A.xlsm").Activate
Set wkb1 = ThisWorkbook
Set wkb2 = Workbooks("A.xlsm") ----THIS LINE RETURNS THE ERROR----
Set sht1 = wkb1.Sheets("Product codes")
Set sht2 = wkb2.Sheets("Product")
sht1.Range("A8:AZ65000").Copy
sht2.Range("A4").PasteSpecial xlPasteValues
Application.CutCopyMode = False
wkb2.Close True
Application.ScreenUpdating = True
End Sub
I also tried this code and it's not working
Sub CopySourceToTarget()
Dim Source As Range, Target As Range
Set Source = Workbooks("Local Codes Creation1.xlsm").Worksheets("Product Codes").Range("A8:AZ6500")
Set Target = Workbooks("A.xlsm").Worksheets("Products").Range("A4:AZ7500")
Source.Copy Destination:=Target
End Sub
Set wkb2 = Workbooks("A.xlms")
Replace this line to
Set wkb2 = Workbooks.Open("Your Path") for example
Set wkb2 = Workbooks.Open("G:\Book1.xlsm")
only worbooks.open require full filename , i mean with path.
For workbooks() , you use as argument only the file name, or index.
See microsoft help for more info.
And for the case the workbook is not opened already, wich can and will happen, you need an error handling.
Other way, without error handling , loop in each workbook in workbooks , if name is same as the one you need exit loop.

Outlook VBA find last Row in Excel Worksheet

I'm writing a function in Outlook VBA that involves reading content from an excel workbook.
The part I'm struggling with is finding the last row in a column (column A in this example). While the 1st line in the highlighted block correctly displays the content of A1 cell in given worksheet, the second line gives a Error "424" - object required.
Any suggestions into the problem would be greatly appreciated.
Public Function openExcel()
Dim xlApp As Object
Dim sourceWorkBook
Dim sourceWorkSheet
Dim cellVal As String
Dim lastRow As Long
Set xlApp = CreateObject("Excel.Application")
With xlApp
.Visible = True
.EnableEvents = True
End With
Set sourceWorkBook = xlApp.Workbooks.Open("C:\SAMPLEPATH\Template.xlsx")
Set sourceWorkSheet = sourceWorkBook.Worksheets("Sheet1")
sourceWorkBook.Activate
With Activesheet
cellVal = sourceWorkSheet.Cells(1, 1)
lastRow = sourceWorkSheet.Cells(.Rows.Count, "A").End(xlUp).Row
End With
sourceWorkBook.Save
sourceWorkBook.Close
xlApp.Quit
End Function
If you want to have the ability to use Excel constants within your code, you will need to either
a) Include a reference to a Microsoft Excel Object Library, or
b) Create your own constant, e.g.
End(-4162)
or
Const xlUp As Long = -4162
...
... End(xlUp)

Copy The Code from one sheet to another

I am trying to write a code that create another sheet and paste the code of the second sheet on it, the program also will delete the sheet if it already exists
Application.DisplayAlerts = False
Sheets("Calcs").Delete
Application.DisplayAlerts = True
With ThisWorkbook
.Sheets.Add(after:=.Sheets(.Sheets.Count)).Name = "Calcs"
End With
Dim CodeCopy As VBIDE.CodeModule
Dim CodePaste As VBIDE.CodeModule
Dim numLines As Integer
Set CodeCopy = ActiveWorkbook.VBProject.VBComponents("Sheet2").CodeModule
Set CodePaste = ActiveWorkbook.VBProject.VBComponents("Calcs").CodeModule
numLines = CodeCopy.CountOfLines
CodePaste.AddFromString CodeCopy.Lines(1, numLines)
Is not working and I dont know why
I think it's not working because of the name of your sheet. In the VBA Project window you can see that your sheets have two names: Sheet1 (Sheet1). So when you add your sheet and rename it, the name will be Sheet##(Calcs) but when you write ActiveWorkbook.VBProject.VBComponents("Calcs").CodeModule you need to use "Sheet##" which is the codename instead of "Calcs".
It is better explained here:
Excel tab sheet names vs. Visual Basic sheet names
What I suggest is to declare your sheet when you create it and write ...VBComponents(TheNameYouDeclared.CodeName).CodeModule
The code you gave us plus what I suggest gives you:
Application.DisplayAlerts = False
Sheets("Calcs").Delete
Application.DisplayAlerts = True
With ThisWorkbook
.Sheets.Add(after:=.Sheets(.Sheets.Count)).Name = "Calcs"
End With
Dim MySheet As Worksheet
Set MySheet = ThisWorkbook.Sheets("Calcs")
Dim CodeCopy As String
Dim CodePaste As String
Dim numLines As Integer
CodeCopy = ActiveWorkbook.VBProject.VBComponents("Sheet1").CodeModule
CodePaste = ActiveWorkbook.VBProject.VBComponents(MySheet.CodeName).CodeModule
numLines = CodeCopy.CountOfLines
CodePaste.AddFromString CodeCopy.Lines(1, numLines)
Is it working for you?
Create a template worksheet containing the code you need - then just copy this to create your new sheet.
In my code I have used the codename of the template sheet rather than the name that appears on the tab (which can be changed outside the VBE) - it's the name not in brackets in your Microsoft Excel Objects and can be updated with the (Name) property in the Properties tab.
Sub Test()
If WorkSheetExists("Calcs") Then
Application.DisplayAlerts = False
ThisWorkbook.Worksheets("Calcs").Delete
Application.DisplayAlerts = True
End If
With shtTemplate 'Use codename rather than actual name.
.Visible = xlSheetVisible
.Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
.Visible = xlSheetVeryHidden
End With
ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count).Name = "Calcs"
End Sub
Public Function WorkSheetExists(SheetName As String, Optional WrkBk As Workbook) As Boolean
Dim wrkSht As Worksheet
If WrkBk Is Nothing Then
Set WrkBk = ThisWorkbook
End If
On Error Resume Next
Set wrkSht = WrkBk.Worksheets(SheetName)
WorkSheetExists = (Err.Number = 0)
Set wrkSht = Nothing
On Error GoTo 0
End Function

Excel 2013 VBA Sheets.Add doesn't return new sheet?

So my code was working fine, until IT upgraded me to Excel 2013 and the SDI interface. Now it looks like the Sheets.Add function doesn't return the proper worksheet. The template is added to the correct workbook (Template1) but when I use the returned worksheet, it's referencing a sheet from the active workbook, before all the VBA code ran.
Public Function Worksheet_AddTemplate(TargetBook As Excel.Workbook, _
TemplateFile as String) As Excel.Worksheet
Dim ws As Excel.Worksheet
Debug.Print TargetBook.Name 'Output-->Template1
Set ws = TargetBook.Sheets.Add( _
After:=TargetBook.Sheets(TargetBook.Sheets.Count), _
Type:=TemplateFile)
Debug.Print ws.Parent.Name 'Output-->Book1
Set Worksheet_AddTemplate = ws
Set ws = Nothing
End Function
Can someone else verify that this is happening to you with Excel 2013, and that there isn't something that I'm missing here.
Thanks
P.S. I use a similar routine to create the template workbook/first sheet with no issues.
Edit: The Code is being called from an Add-In. Here is how I call the Function, more or less (I've simplified the routines because it would be too long otherwise)
Private Sub ImportDataFile()
Dim wb As Excel.Workbook
Dim ws As Excel.Worksheet
Dim sUnit As String, sTemplateFile As String
Dim u As Integer, nUnits As Integer
Application.ScreenUpdating = False
Application.EnableEvents = False
' ...Some setup stuff that I wont bother you with
sTemplateFile = Environ("Temp") & "\Template1.xlt"
For u = 0 To nUnits - 1
If wb Is Nothing Then
Set wb = Workbook_NewTemplate(sTemplateFile)
Set ws = wb.Worksheets(1)
Else
Set ws = Worksheet_AddTemplate(wb, sTemplateFile)
End If
ws.range("H6") = sUnit
' More Loops & writing to cells
For i = 0 To g_Data(f).ItemCount - 1
' Blah, blah, blah
Next
Next
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
I've noticed that if I add 2x DoEvents anywhere in between creating the workbook and adding the second sheet it will work as it did before.
Also, if I use this code in the Worksheet_AddTemplate function it seems to work...
Set wb = Application.Workbooks.Add(Template:=TemplateFile)
Set ws = wb.Worksheets(1)
ws.Copy After:=TargetBook.Sheets(TargetBook.Sheets.Count)
Set ws = TargetBook.Sheets(TargetBook.Sheets.Count)

Opening a workbook with VBA/macro is making it read only?

I would like my code to open a workbook (always the same one), detect the first free row, write to just two cells in that row, and then save/close the workbook. This seems like a simple problem, but the macro seems to be opening a copy of the file, and then locking it for editing.
Can you see any errors in my open code? I know that the file opens and that the row search works, but then it 1. never writes to the cells, and 2. locks the file.
Function WriteToMaster(Num, Path) As Boolean
'Declare variables
Dim xlApp As Excel.Application
Dim wb As Workbook
Dim ws As Worksheet
Dim infoLoc As Long
Set xlApp = New Excel.Application
'Specifies where the Master Move Key is stored
Set wb = xlApp.Workbooks.Open("DOC LOCATION")
Set ws = wb.Worksheets("Sheet1")
'Loop through cells, looking for an empty one, and set that to the loan number
infoLoc = firstBlankRow(ws)
MsgBox "First blank row is " & infoLoc & ". Num is " & Num
ws.Cells(infoLoc, 1).Value = Num
ws.Cells(infoLoc, 2).Value = Path
'Save, close, and quit
wb.Save
wb.Close
xlApp.Quit
'Resets the variables
Set ws = Nothing
Set wb = Nothing
Set xlApp = Nothing
'pieces of function from http://p2p.wrox.com/vb-how/30-read-write-excel-file-using-vb6.html
End Function
Thank you again, stackoverflow <3
Do you need to open a new excel app just to open a workbook?
Can't you just do something like this:
Sub Macro1()
Dim wkb As Workbook
Workbooks.Open Filename:="\User Documents$\bob\My Documents\workbook_open_example.xlsx"
Set wkb = Workbooks("workbook_open_example.xlsx")
End Sub