I have a VBA program that asks for the user to enter a desired range, which is in another opened workbook. If there is an error, i.e. the other workbook is manually activated, but no range is selected, or there is an error, I want the program to display the original macro workbook sheet with an error message. The code below works in Debug mode, but when the VBA program is run, it displays the error correctly but does not display the original macro worksheet. It remains on the sheet that was manually activated by the user. What am I missing?
In the code below, "HMArea" is a Range variable returned by the routine getting user input.
"Macro_Fname" is a string variable for the file name of the original VBA program.
HM_file = FileName(HMArea)
If HM_file = "Macro_Fname" Then
Windows("Macro_Fname").Activate
Sheets("[name of the sheet in Macro_Fname]").Select
Range("D4").Select
MsgBox "ERROR: No data selected"
Exit Sub
End If
Try changing
Windows("Macro_Fname").Activate
to
Workbooks("Macro_Fname").Activate
However, the exact nature of your question is vague. Assuming you are in Workbook A, do you want to select a range in Workbook B (which is open at the same time)?
To refer to macro workbook use ThisWorkbook
When another workbook is opened always assign it to variable so that you can have control over it.
Set wbk = Workbooks.Open("D:\test.xlsx")
When working with multiple workbook always prefix the workbook object. If its ignored it will take active workbook.
`Sheets("[name of the sheet in Macro_Fname]").Select`
Avoid using Select/Acitvate. See here
Range("D4").Select
Once the above issues are fixed your code will run as expected.
Related
Sub test()
Worksheets("Sheet1").Range("A1").Value = 20
End Sub
This simple code is giving error when I compile it.
activesheet. works fine.
I want to know whats resulting in an error and how to fix it...
looks like it's not identifying the sheets, workbook etc.
The answer depends on which error you get. There can be 2 issues:
1. Workbook not specified
You have more than one workbook and Excel is looking in the wrong workbook for your sheet named "Sheet1", then you need to specify the workbook.
Workbooks("my-workbook").Worksheets("Sheet1").Range("A1").Value = 20
or if it is in the workbook where the code is running at it is better to use
ThisWorkbook.Worksheets("Sheet1").Range("A1").Value = 20
Note that you should avoid ActiveWorkbook which is not very reliable.
2. Wrong worksheet name
There is no worksheet named Sheet1. Check your worksheet names. Note that there are different ways to specify a worksheet.
Specify by number
Worksheets(1).Range("A1")
This uses the position of the worksheet in the tab bar below the worksheets. Note that is not very reliable because position can easily be changed by moving the tabs around.
Specify by tab name
Worksheets("Sheet1").Range("A1")
This is probably the most common method. The worksheet is specified by its tab name. This is more reliable than by number.
Specify by VBA name
Sheet1.Range("A1")
Here the VBA name of the sheet is used. This name can only be changed in the VB editor and is not visible to the user, and has nothing to do with the tab name. Using this ensures that the VBA code still works on the desired worksheet even if a user changes the tab name of the worksheet.
So if the tab name is Sheet1 its VBA name can be Sheet5 and it can be on position 3 in the tab bar.
Using this example …
Worksheets("Sheet1").Range("A1")
Sheet5.Range("A1")
Worksheets(3).Range("A1")
… are all 3 accessing the exact same worksheet just by different names. So better to use meaningful names (and no numbers) here to not confuse.
I have a workbook ("CodeBook.xlsm") that runs code using a BeforeSave event. When a user has multiple workbooks open and chooses to quit excel via File/Exit, the user is prompted whether to save workbooks, and if yes to CodeBook.xlsm, then the BeforeSave code is run. The problem is, at that point the ActiveWorkbook may not be CodeBook.xlsm, unless that happens to be the workbook that the user was in when he/she selected Exit Excel. If the user quit excel from another workbook, the BeforeSave code is running but the activeworkbook is some random file of the user, so all the references to specific worksheets and ranges in the BeforeSave code do not work.
I have tried various ways using a Static declaration to retain the name of CodeBook and workbook().activate to activate it when the application is quitting, but when BeforeSave runs, it can't pick up the name CodeBook anywhere, short of hard-coding the name into the code.
Any suggestions? How to retain a variable name in memory when there is no code running, but is there when a user initiates a quit excel, OR how to activate a specific workbook when Excel is quitting from a user command and not from application.quit. Using excel 2010.
I overcame this by including a reference to the specific workbook.
For example, this code simply saves the date/time stamp in cell A1 of Sheet1 before closing the document. By adding ThisWorkbook, it works on the specific workbook that the code resides in. If you don't add ThisWorkbook then it will work on the active workbook when the user quits.
Private Sub Workbook_BeforeClose(Cancel As Boolean)
ThisWorkbook.Worksheets("Sheet1").Range("A1").Value = Now()
End Sub
Place this code in the ThisWorkbook module.
I am trying to copy values from one sheet to another and getting this error
"Run Time error 9 : subscript out of range"
when I run the code below.
Sub updatemultiple()
Workbooks.Open ("C:\Users\akpeko.zigah\Documents\EDC\DESTINATION.xlsm")
Range("B2:F2").Copy
'Application.DisplayAlerts = False
ActiveWorkbook.Close
ActiveSheet.Paste Destination:=Worksheets(“Sheet1”).Range("B2:F2")
End Sub
Any help? I'm stuck.
There are a number of unanswered parentage questions to your workbook/worksheet/cell references but if you are pasting into the same workbook as the one containing the code then something like this should work.
Sub updatemultiple()
Workbooks.Open ("C:\Users\akpeko.zigah\Documents\EDC\DESTINATION.xlsm")
Range("B2:F2").Copy Destination:=THISWORKBOOK.Worksheets(“Sheet1”).Range("B2")
'Application.DisplayAlerts = False
ActiveWorkbook.Close False
End Sub
The problems start with how you are determining the currently active worksheet when you open the external workbook. If it was opened, the active worksheet changed then closed byt another person or process then when you opened it it is going to copy the wrong cells. If the destination worksheet is not contained in the workbook containing the code then the destination is an ambiguous reference that depends upon the current state of the application environment.
A short rewrite of your code (with some made-up references thrown in) might be like the following.
Sub updatemultiple()
Dim wb As Workbook
Set wb = Workbooks.Open("C:\Users\akpeko.zigah\Documents\EDC\DESTINATION.xlsm", ReadOnly:=True)
With wb.Worksheets("Sheet1")
.Range("B2:F2").Copy Destination:=ThisWorkbook.Worksheets(“Sheet1”).Range("B2:F2")
.Close SaveChanges:=False
End With
Set wb = Nothing
End Sub
In short, be as explicit as you can by defining the workbook, worksheet and cell references for each side of every operation. Relying on 'what is active' can only lead to trouble.
If I understood your code correctly, it seems to me that you have the code in one file. When you execute the code, it opens the DESTINATION.xlsm file, copy the cells, close the DESTINATION.xlsm file, then paste the data in the active sheet of the original file that contains the code.
I don't know what data you're copying, but when you copy (manually, not in code) a lot of data from an excel file and then you close it, you get a warning:
There is a large amount of information on the Clipboard. Do you want to be able to paste this information to another program later?
For that reason, I recommend you to paste your copied cells first, and then close the file you're copying from.
I am running VBA code from Access 2010 that opens an Excel 2010 workbook ("Master"), then copies specified sheets from "Master" to a "Client" workbook. This has worked fine until I got to one particular worksheet, where I get:
Run-time error '1004': Copy method of Worksheet class failed
The line of code is:
XLMaster.Sheets(SlideRS.Fields(2).Value).Copy _
After:=XLClinic.Sheets(XLClinic.Sheets.Count)
In this particular instance, this is the 2nd sheet being copied, so the code worked the first time through. This is part of a long debugging process, and this line of code has worked great for more than a dozen other worksheets from the same "Master" workbook.
Oddly, the copy fails when I try to do it manually, as well. I've opened "Master", right clicked the particular worksheet that's failing, and tried to copy it, and it just simply fails to do so. I can manually copy other worksheets within the workbook just fine.
The only difference I can identify is that this particular worksheet has 2 pivot charts on it. Other worksheets that copy OK have just data, charts (of varying types), and even pivot charts and regular charts. This is the only one that has only pivot charts and not 'regular' charts. Not sure if that's the cause, but that's the only thing I can identify that's possibly different.
For greater context, the line of code comes from this loop:
While Not SlideRS.EOF
If SlideRS.Fields(1) <> SlideRS.Fields(2) Then
'the worksheet depends on something else, copy it first
'if the depended upon slide is not in the list of UsedSlides, then add it
If InStr(1, UsedSlides, SlideRS.Fields(2)) = 0 Then
XLMaster.Sheets(SlideRS.Fields(2).Value).Copy _
After:=XLClinic.Sheets(XLClinic.Sheets.Count)
Set NewSheet = XLClinic.Sheets(XLClinic.Sheets.Count)
UsedSlides = UsedSlides & "," & NewSheet.Name
UpdateCharts XLMaster.Sheets(SlideRS.Fields(2).Value), NewSheet
ProcessDataSheet NewSheet, NewXLName
Set NewSheet = Nothing
End If
End If
SlideRS.MoveNext
Wend
Again, this code works just fine, it's just this one particular sheet that doesn't want to be copied, either by code or by hand.
Here is what happens when I attempt to copy it by hand in the "Master" spreadsheet.
In a freshly opened copy of my "Master" workbook, I opened the code window and executed Application.DisplayAlerts = True in the immediate window (just to be sure), then,
the worksheets before the copy: VisitsByDemo is the sheet being copied
The copy setup:
And after the copy:
There is no error message generated by Excel.
It turns out the the PivotCharts were broken.
When I attempted to edit the data source for the PivotCharts, this is what Excel showed me:
When I recreated the PivotCharts on that page, then edit the data source, this is what I see:
Not sure what happened, but since I created new versions and deleted the originals, Worksheet.Copy() works just fine.
I've had a some success creating a project script that throws up some dialogues to take information, place it on a worksheet (activex box) and then print.
My code runs fine when located in Sheet1 object with the VB editor. However, I want it to run on excel open, so I paste it into the thisworkbook object within workbook_open(), but nothing works.
Can anyone explain to me how I can get this script to run upon excel open, or cease to receive the 424 error when running it from workbook_open()?
The debugger doesn't like my labelbatch and labelexpiry objects (but only when in thisworkbook), but it works fine otherwise.
Private Sub Workbook_Open()
ActiveWorkbook.Sheets("sheet1").Activate
'Clears label fields prior to data entry
labelbatch.Caption = ""
LabelExpiry.Caption = ""
'Auto input of batch code into batch field using input text.
BatchNo = InputBox("Enter batch code", " ")
labelbatch.Caption = BatchNo
'Auto input of expiry date into expiry field using input text.
ExpiryDate = InputBox("Enter expiry date", " ")
LabelExpiry.Caption = ExpiryDate
'Show print dialog box
Application.Dialogs(xlDialogPrint).Show
'Close without saving changes
ActiveWorkbook.Close False
End Sub
Assuming labelbatch and labelExpiry are objects on the worksheet, when the code is moved to ThisWorkbook VBA doesn't know where to look for those objects. Use e.g.
thisworkbook.worksheets("Sheet1").labelbatch
to refer to them.
When you use a method or property name without all its parents, VBA will either throw an error or will use a default depending on the context. For example, for Cells(), Range() and the like, that default is Application.ActiveSheet. That is generally risky: it's very hard to be sure what the active worksheet will be if you later change your code (or even if a user switches sheets while your code is running). Better to specify which worksheet you want.
This does make references to objects longer, but you can always use With...End With to help readability and save typing.