VBA subscript out of range, code 9 - excel

I'm conducting my very first VBA macro and I'm having some difficulties with this seemingly easy code to read data from a closed workbook into my currently opened one.
Sub KAuto()
Dim path As String
path = "C:\files\Utfall.xlsx"
Dim currentWb As Workbook
Set currentWb = ThisWorkbook
Dim openWb As Workbook
Set openWb = Workbooks.Open(path)
Dim openWs As Worksheet
Set openWs = openWb.Sheets("March")
currentWb.Sheets("Indata").Range("A1").Value = openWs.Range("A3").Value
End Sub
The problem I'm having is that I get a code 9, subscript out of range. But I've checked that A1 and A3 is existent for the current workbook and the imported one respectively.
What I have tried to do is to omit the ".Value" in all combinations, as that was what the original author did.
Googling this problem I've encountered that people misused functions which I do not use, for instance windows(), or omitted "" for referencing the worksheets, or simply misspelled things. I don't Think I have any of these, and so I need further help.
How can I correct my subscript out of range? Is there a better way to achieve this copying of cells? In the future I want to import 10 files, will this then be obsolete? (I recall someone posting something in the lines of openWb = [file1,file2,file3] and looping through them, but I cannot find it; does anyone have a link?
EDIT: I've copied the path to the file from its properties, so it ought to be correct.
EDIT2:
currentWb.Sheets("Indata").Range("A1").Value = openWs.Range("A3").Value
snippet gives the error
EDIT3: VB editor print screen:

Try using ActiveWorkbook instead of ThisWorkbook.
Set currentWb = ActiveWorkbook
ThisWorkbook refers to the workbook in which the code resides. ActiveWorkbook refers to the workbook that is currently active i.e. "on top" in the Excel application. It looks like your case, the code resides in a different workbook; so what you want is ActiveWorkbook.
And you can ommit the .value from last line.
currentWb.Sheets("Indata").Range("A1") = openWs.Range("A3")
Your code worked fine for me, that`s why I cannot be sure if it will help. There can be an issue, when opening the openWs. The error line can be evaluated before the openWs is actually open. Then maybe add a line :
Application.Wait (Now + TimeValue("00:00:03")) 'this is 3 seconds from now
after the Set openWb = Workbooks.Open(path).

Related

Visual Basic 438 Error When Assigning String to Cell

I copied this text from the "Introduction to Excel VBA Programming" textbook by Guojun Guo:
Sub AccessObject()
Application.ActiveWorkbook.Sheets(1).Cells(1,2).Value = "A String"
End Sub
I get a 438 Error. When I get rid of the Application.ActiveWorkbook.Sheets(1) prefix the code runs. I do not know why this prefix gives the 438 Error. Is this just deprecated or are my settings wrong?
Thanks!
edit: see additional material at the end in response to this comment
It's possible to have sheets in a workbook which aren't worksheets and thus don't have cells. Chart sheets are an example of this. You can check which type of sheet that Sheets(1) is by adding this to your code:
MsgBox Application.ActiveWorkbook.Sheets(1).Type
If the value displayed in the message box is -4167, then Sheets(1) is a worksheet. For anything else, consult the values for xlSheetType
But the simpler solution is to change to using Worksheets(1) instead, because that will only look at worksheets. You can also remove Application.ActiveWorkbook (edit: but see below) because that is the default, which leaves you with:
Worksheets(1).Cells(1, 2).Value = "A String"
edit: As pointed out in this comment, Application.ActiveWorkbook is not the default when the code in question is in a ThisWorkbook module. So, either specify ActiveWorkbook if you want your macro to affect whichever workbook is currently active (there shouldn't be any need to specify Application though):
ActiveWorkbook.Worksheets(1).Cells(1, 2).Value = "A String"
Or, if you want your macro to affect the same workbook that the macro code is in, either specify ThisWorkbook in a normal module:
ThisWorkbook.Worksheets(1).Cells(1, 2).Value = "A String"
Or put the code in the ThisWorkbook module and don't specify anything about the workbook:
Worksheets(1).Cells(1, 2).Value = "A String"
Or, if you want the code to affect a specific workbook that isn't the one which contains the macro and isn't necessarily the active workbook, then capture a reference to that other workbook in a variable and refer to that. A common way to do this is when you open that other workbook:
Dim wb As Workbook
Set wb = Workbooks.Open("filename goes here")
' do stuff
wb.Sheets(1).Cells(1, 2).Value = "A String"
' do other stuff - including potentially saving the workbook
wb.Close
Set wb = Nothing

How do you select a specific cell on a specific sheet excel VBA? [duplicate]

During the process of running a script if I manually remove focus from the Workbook containing the macro I get the error quoted. If I don't click on anything it works without issue. Script errors out only when I'm trying to place selection back into A1 from the "Input" sheet. Break point is on following line:
ThisWorkbook.Sheets("Input").Range("A1").Select
If I debug and place focus back on macro Worksheet the script completes without issue. Previous line:
ThisWorkbook.Sheets("Input").Cells.Delete
runs without error so I'm guessing its the range that is falling out of scope but don't quite understand why as it should be defined by the previous scope notations.
Can someone explain why that line is falling out of scope? Shouldn't the ThisWorkbook define fairly explicitly the Workbook that my code is referencing? Any guidance is greatly appreciated.
It doesn't have anything to do with the reference to ThisWorkbook at all. You simply can't Select a Range in an object that isn't active. Consider this code, which exhibits the same error:
Private Sub OneOhOhFour()
'Executing with Book1.xlsm active and Book2.xlsx open.
Dim wb As Workbook
Set wb = Application.Workbooks("Book2.xlsx")
Debug.Print ThisWorkbook.Name
'Outputs 'Book1.xlsm' to Immediate window.
wb.Sheets("Sheet1").Range("A1").Select 'Error 1004
End Sub
Same thing with Worksheets:
Private Sub OneOhOhFourVTwo()
'Starting on anywhere but Sheet2 gives an error.
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet2")
ws.Range("A1").Select 'Error 1004.
End Sub
The simple solution is to Activate the object before you Select within it:
Private Sub NoOneOhOhFour()
Dim wb As Workbook
Set wb = Application.Workbooks("Book2.xlsx")
wb.Activate
wb.Sheets("Sheet1").Range("A1").Select 'No error.
End Sub
Even better is using references and trying to avoid using the Selection and Active* objects entirely.

Trying to Copy Workbook data but when Source opens nothing happens

I'm using the following code:
Dim sourceBook As Workbook
Dim targetBook As Workbook
'## Open both workbooks first:
Set targetBook = Application.ActiveWorkbook
Set sourceBook = Application.Workbooks.Open("...\Documents\Log.xlsm")
'
With sourceBook.Sheets("Sheet1").UsedRange
'Now, paste to y worksheet:
targetBook.Sheets("Sheet1").Range("A1").Resize( _
.Rows.Count, .Columns.Count) = .Value
End With
'Close
sourceBook.Close
But when i run it my source book opens and nothing happens after. Not sure what i'm missing. Both workbooks have the same extension xlsm. Ive tried to change the source to xlsx also but Same result
Edit: Ive replaced the with statement with the following:
targetBook.Sheets("Sheet1").Range("A1").Value = sourceBook.Sheets("Sheet1").Range("A1")
to at least see if i can copy 1 value but when the sourcebook is opened it stops there.
I have recreated your example, and think it is do with the way you are opening the document. In your open method you have three dots Open("...\documents")
It raised an error for me, so can you check that is what you meant? It worked if I used ..\ rather than ...\

passing variables from multiple workbooks to one workbook

I am using Visual basic from excel to open a different workbook and pass some things from one to another. I have the second file opening fine however I cant get the second file to read the things I need.
Sub createExcel()
Cells(1, 1).Text = "va02"
Dim objExcel
Set objExcel = CreateObject("Excel.Application")
objExcel.Visible = True
Set objWorkbook = objExcel.Workbooks.Open(filepath)
End Sub
this is my code to open the second application. I have 2 variables in 2 cells in the first workbook. How would one go about getting the variables. the problem i have encountered is; the second workbook can be called from any file, in any folder.
i would try
variable = Workbooks(firstWorkbook.xlsm).worksheets(sheet1)...
however the worksheets dont have the same names either. please help
thanks
Your code is in Workbook1, and opens Workbook2. So it's Workbook1 that does everything - so " I cant get the second file to read the things I need" is not meaningful.
Sub Demo(filepath as string)
ThisWorkbook.Worksheets(1).cells(1,1).text = "This is written by initial Workook"
Dim Wb as Workbook
Set Wb = Workbooks.Open(filepath)
Wb.Sheets(1).cells(1,2) = "So is this, even though it's in a different workbook"
End Sub

VBA: Paste ceases to work (suddenly) in specific macro

I'm a very new, self-taught programmer, so please keep this in mind in your responses. I have extensively searched this and other forums and can't seem to find a similar question.
The following code has been working for weeks and has not been changed. (My macro includes more variables and code, but I know from taking it apart that those pieces work, so I've left them out for clarity). From what I can tell the PasteSpecial function is specifically not working.
Dim StimSheet As String
ActiveCell.Rows("1:290").EntireRow.Select
Selection.Copy
'Copies the data for the current stimulus
StimSheet = Application.InputBox("Enter the name of the stimulus")
'asks name of the stimulus
Sheets.Add After:=Worksheets(Worksheets.Count)
ActiveSheet.Name = StimSheet
'adds new sheet at the end and names whatever you input as stimulus name
Sheets(StimSheet).Select
Selection.PasteSpecial Paste:=xlPasteValues
'pastes data into new sheet
At this point there is no error, the macro simply stops after copying and creating the new sheet.
Here's what I know / have tried:
The macro is successfully making and naming the new sheet and copying the selection to the clipboard, because I can manually paste it after running the macro. It seems to be getting stuck at the paste piece.
Other macros that use the exact same format of copy / paste special are still working correctly.
Another forum with a similar program suggested typing "Application.EnableEvents=True" into the immediate window. This did not change anything.
This macro has worked for several weeks with no errors. I have made new macros using previously saved code in case something inadvertently was changed in the current one, but this did not work either.
The paste option will work one time on a new file and then ceases to work again.
Thank you in advance for your suggestions.
You might find the problem is that you don't have much control over which workbook and worksheet this code applies to. It's better to avoid ActiveSheet, Select, and Sheet with no parent as much as you can.
If you only need to copy the values of cells without any formatting, then Paste isn't needed either.
Try changing your code to the following and see if you have any better luck:
Const BOOK_NAME As String = "Book1.xlsm" 'change this to your workbook name
Const SOURCE_SHEET_NAME As String = "Sheet1" 'change this to your sheet name
Dim wb As Workbook
Dim sourceSheet As Worksheet
Dim newSheet As Worksheet
Dim newSheetName As String
Dim validName As Boolean
Dim rng As Range
' Set the book, sheet and range objects
Set wb = Workbooks(BOOK_NAME)
Set sourceSheet = wb.Worksheets(SOURCE_SHEET_NAME)
Set newSheet = wb.Worksheets.Add(After:=wb.Worksheets(wb.Worksheets.Count))
' Acquire the new sheet name and check it's valid.
Do
newSheetName = InputBox("Enter the name of the stimulus")
On Error Resume Next
newSheet.Name = newSheetName
validName = (Err.Number = 0)
On Error GoTo 0
If Not validName Then MsgBox "Sheet name isn't valid. Try again."
Loop Until validName
' Write the values into the new sheet
Set rng = sourceSheet.Cells(1, 1).Resize(290, sourceSheet.UsedRange.Columns.Count)
newSheet.Range(rng.Address).value = rng.Value2
I moved this line:
StimSheet = Application.InputBox("Enter the name of the stimulus")
to the top of the method and it seems to work reliably. I wish I could tell you exactly why, but at least you can proceed. Perhaps it has something to do with the focus changing.
Also, when it failed for me (Office 2013) I got the following error:
Run-time error 1004:
Application-defined or object-defined error.
When the Sub was in a Sheet code behind, and this:
Run-time error '1004'
PasteSpecial method of Range class failed.
When pasted in a Module.

Resources