So I'm a bit new to excel VBA, and I'm creating a macro to run on financial worksheets. I want to shift the values in the totals to the right place, as they are a column to the left of the actual data (these weren't created by a formula, they were generated by a different program and are fixed text). The shifting I managed to do just fine. The problem here is finding where the totals column is, as it varies between worksheets.
This is what I have so far.
For totalRow = 7 To 2000
With ws
If ws.Visible = True Then
If InStr(Range(totalRow, "A").Value, "Totals:") > 0 Then
Exit For
End If
End If
End With
Next totalRow
Yet for some reason, it's giving me an error when I try to run it. I know it's probably something simple I'm overlooking, because I cannot for the life of me figure out the problem. I've tried using a Do-Until loop, same issue. Is it a problem with the variables I'm using?
Several suggestions:
This is the basic problem:
Error 1004 "Application-defined or Object-defined error"
Look here for several potential issues/potential fixes:
VBA Runtime Error 1004 "Application-defined or Object-defined error" when Selecting Range
Use the VBA debugger and step through your macro a line at a time, until you find the specific object it's barfing on:
https://www.techonthenet.com/excel/macros/vba_debug2013.php
EDIT:
Having said that, I think Tim Williams's suggestion is probably spot-on:
You should always scope your Range/Cells calls with a worksheet
object, otherwise they will reference whatever happens to be the
Activesheet.
But PLEASE:
If at all possible, make the effort to learn troubleshooting tools available to you (like the debugger).
One other "useful tips" link I'd urge you to look at:
http://www.jlathamsite.com/Teach/VBA/WritingBulletProofCode.pdf
Related
Please read this fully and understand that this program was working fine until I changed the way I was hiding the workbook.
I have a program that worked great while I was using Application.Visible = False and only showing the user form. I came to realize that this would hide all Excel windows and not just the one I was using. This is going to be distributed throughout the department and hiding all Excel windows was unacceptable.
I started using ActiveWindow.Visible = False, but I am now getting Error 91 anytime I search a worksheet for a value (Cells.Find).
Modifying the worksheet is not an option and the value for which I'm searching can move around the sheet depending on what has been added or removed.
Cells.Find worked out great for this reason. I need to either find another way to search the page, or find another way to hide the worksheet. Please help
When the window is not visible, the Cells reference is not qualified to a worksheet object (unless qualified, Cells refers to ActiveSheet.Cells and there is no ActiveSheet), so you can do like:
Sheets("sheetname").Cells.Find ' modifying "sheetname" as needed
This may also fail (with the same error), or it could also yield incorrect results if there are other open workbooks, so it's best to qualify to a workbook fully, e.g.:
Workbooks("workbookname").Sheets("sheetname").Cells.Find(...
It is still a good idea to test the result of Find before performing additional method/property calls against an object which could be Nothing, as per this answer:
Find command giving error: "Run-time Error '91': Object variable or With block variable not set"
I'm experiencing a strange issue occurring with my VBA Macros in Excel. Background is, I'm creating a template for Labour Logs to log hours that employees are on site. There is a main sheet where all the data is entered "Labour Log" and then 8 sheets, one for each of the days of the week and a Holidays sheet. There is a hidden sheet where my dynamic list and static lists are held.
The macros that are causing issues are the ones on the sheets for the days of the week. What they are doing is, searching the Labour Logs sheet for any cell with that day of the week in column B, then inserting that line on row 8 of the day sheet. This loops until all instances are entered. Example of Monday below.
Private Sub PullMondayData_Click()
Dim dc As Range
With Sheets("Labour Log") 'Reference to Labour Log Sheet
For Each dc In Intersect(.Range("B:B"), .UsedRange)
If dc.Value2 = "Monday" Then 'Search/Filter B:B for Monday
dc.Resize(1, 1).EntireRow.Copy 'Copy the row
Sheets("Monday").Rows(8).Insert Shift:=xlDown 'Insert in Row 8, shifting down
End If
Next
End With
Application.CutCopyMode = False 'Remove copy mode
End Sub
This usually works fine for Monday. I can usually hit that one multiple times without issue.
When I go back to the Labour Log sheet and change the day to any other day, I start getting errors on those sheets when hitting the macro. The macro codes is exactly the same, but with the relevant day entered in the correct spots.
The first error I usually get is:
Going to debug says error with this line:
I then stop the macro and run it again, getting the following error:
Debugging it gives this line:
After that, the only way I can close the Excel sheet is to end the process form the Task Manager, the rest of the program is locked.
From time to time, I also get a crash, and the output is this:
Problem signature:
Problem Event Name: APPCRASH
Application Name: EXCEL.EXE
Application Version: 16.0.6868.2060
Application Timestamp: 5723a711
Fault Module Name: mso20win32client.dll
Fault Module Version: 0.0.0.0
Fault Module Timestamp: 57222bc3
Exception Code: c0000005
Exception Offset: 0008c78d
OS Version: 6.1.7601.2.1.0.256.48
Locale ID: 4105
Additional information about the problem:
LCID: 1033
skulcid: 1033
I've searched online for various answers, but they don't seem to work. I've tried the following:
Clearing the Excel folder in C:\Users\User_Name\AppData\Roaming\Microsoft\Excel
Cleaning the Registry
Changning the set printer (long shot, but saw a few people say it worked)
Running another day before Monday
Running Windows Update
Moving Application.CutCopyMode = False within the If loop
My knowledge of VBA isn't great and a lot of this code was taken from searches and altered to suit my purpose, but I don't understand why it is working for the Monday sheet, but crashes on all others.
Any insight would be much appreciated.
Thanks.
too little info to actually track that error down
but, assuming you're using a Userform with many buttons to click and have proper day processed, I'd propose you some code that can possibly help you keep things cleaner and, therefore, less prone to errors
set your buttons caption property as per the relevant day
so you'll have
PullMondayData button showing "Monday" caption on it
PullTuesdayData button showing "Tuesday" caption on it
and so on
have all your Pulldaybutton "Click" event handlers code just like follows:
Private Sub PullMondayData_Click()
PullDayData (Me.ActiveControl.Caption)
End Sub
Private Sub PullTuesdayData_Click()
PullDayData (Me.ActiveControl.Caption)
End Sub
and so on
add the following sub to your Userform code pane
Private Sub PullDayData(thisDay As String)
Dim dc As Range
With Sheets("Labour Log") 'Reference to Labour Log Sheet
For Each dc In Intersect(.Range("B:B"), .UsedRange)
If dc.Value2 = thisDay Then 'Search/Filter B:B for Monday
With Sheets(thisDay).Rows(8)
.Insert Shift:=xlDown 'Insert in Row 8, shifting down
.Value = dc.Resize(1, 1).EntireRow.Value
End With
End If
Next
End With
End Sub
all what above can still greatly improved, but it'll give you at least the following benefits:
write much less code
and thus both make much less effort in maintaining it and possibly have many few errors!
not make use of copy/paste methods to both not passing through clipboard and be faster
For further effective improvements I'd suggest you the following steps:
use AutoFilter() and SpecialCells() methods of Range object to improve both control and efficency
use classes
While I agree with user3598756 that this isn't enough to give an answer with certainty, I do have some additional things to try:
I've had much better results using .CurrentRegion, than .UsedRange to get the area of data. There are exceptions, but if you have headers that can't be blank and at least one column with no blanks, it works flawlessly.
When you have more than one thing on a line causing an error, breaking it out will give you better info about crashes, so change: dc.Resize(1, 1).EntireRow.Copy into two statements: dc.Resize(1,1) and dc.EntireRow.Copy.
COM objects, and Range objects like .Rows(x) in particular, are tricky beasts. This seems to be worse in C# addons than VBA macros, but I've often seen them not update as expected when you do something to major their contents. The work around is the general case of the specific case I gave in point 2: one dot good, two dots bad. For example instead of calling Sheets("Monday").Rows(8).Insert try something like:
Dim MondaySheetRow as Range
MondaySheetRow = Sheets("Monday").Rows(8)
MondaySheetRow.Insert Shift:=xlDown
Lastly I've made a habit of not updating sheets that aren't active. Instead I activate the sheet I'm going to make changes to, make the changes, then return to the originally active sheet. This mimics the way a user would manually make the changes which also helps visually show where the macro went in the calls leading up to an error.
BACKGROUND:
I am trying to identify how many unique time periods I have from a list of dates that have. Elsewhere, I have seen a method which utilizes collections and error trapping (right term? I mean "On Error Resume Next" in any case) to build the collection with unique values. I have even used this structure successfully in other code that I have written, but in my current circumstance, I am getting an "Error 457: This key is already associated with an element of this collection." Thinking I was using the collection incorrectly, I opened up some older code I wrote 6 months ago (on a different computer for a different company) which uses the same structure and was known to WORK. This older code broke on the same identical error, which it previously did not do. Here is the sample of my work-in-progress code:
Dim rng as range
Dim TimePeriod as Collection
Set TimePeriod = New Collection
For Each rng In Range("I2:I6")
On Error Resume Next
TimePeriod.Add rng.Value, CStr(rng.Value) 'This is where the code breaks
On Error GoTo 0
Next rng
QUESTION:
I'm wondering if there is a setting or a reference library that I am somehow missing that is causing both pieces of code to break, or how to determine that, since both codes are functionally identical, and the previously tested satisfactory code breaks like my work-in-progress. I expected the "On Error Resume Next" to force the loop to pass over the error. Any suggestions?
--Update--
Sample data in range("I2:I6") as follows:
1/21/15
1/21/15
1/21/15
1/23/15
1/27/15
Your code works properly on my Excel 2007, although I would rewrite it to enclose the entire loop within the on error resume next for efficiency.
I suspect you are seeing the errors now because of a mis-set macro option error break.
Check Tools/Options that you have not selected to Break on All Errors
Try getting rid of the On Error Goto 0 line. Take a look at this:
Difference between 'on error goto 0' and 'on error goto -1' -- VBA
It comes from Visual Basic 6, but works pretty much the same in VBA, it appears. Should work if you keep the On Error Resume Next line but eliminate the On Error Goto 0 line.
I am a bit suprised as I am trying to record a macro in Excel, but I keep getting this error:
Cannot Run Visual Basic Editor Because of a Syntax error
The most surprising part is that I am not trying to run any macro yet, just trying to record it.
The first time I noticed this I tried to record something like
vlookup(Today(),Sheet2!A1:B2,2)
Initially I assumed it was an error in the formula I typed, but then I noticed that the correct value was displayed in the sheet.
Now I have a module that looks like this, and each time I try to record something the error pops up.
Option Explicit
Sub Macro34()
ActiveCell.FormulaR1C1 = "=TODAY()"
End Sub
Sub Macro35()
ActiveCell.FormulaR1C1 = "=5"
End Sub
I have written some other macro code in other modules, but that is not supposed to run at the moment (and I didn't see any errors in it as well).
I have searched for this error but each found result is about someone trying to run a macro. It is really annoying me so I hope someone can tell me how to get rid of this error.
If I recall correctly, this problem occurs after working on the same Excel file repeatedly.
Each time a new module is created to record macro's, and after the ninth one Excel doesn't know what to do.
Changing the name of the modules, or removing some solved the problem for most recording functions.
You're trying to run macros when the Macro Recorder is on - turn it off
Set mainWB = Workbooks("Copy Paste.xlsb")
Set mainWS = mainWB.Sheets("Sheet1")
Set testWS = mainWB.Sheets("Sheet3")
mainWS.Select
I keep getting an error on the last line in Excel VBA:
"Method Select of Object '_Worksheet' failed"
Any idea why or how to fix this? Thank you!
As discussed in comments, cannot select Sheets in VBA that are not active (or Range objects on them).
For example the following code
Sheets(1).Activate
Sheets(2).Range("A1").Select
will cause the error you are receiving.
In your case, it seems you are attempting to Select a sheet which is not active - your mainWS object is presumably not the ActiveSheet at the point you are calling this code. An easy way to test if this is happening is if you add the following to the end of your code:
if (ActiveSheet.Name <> mainWS.Name) then
msgbox ("Going to crash after clicking ok!")
end if
mainWS.Select
Note that you can refer to the activated worksheet with the command ActiveSheet to either get properties or whatever other operations you are interested in doing.
This error can also happen if you have loop working thru all of the worksheets in the workbook and there are hidden sheets. Lookout for that.
Last, and unrelated to your specific error message, I assume you are declaring those variables somewhere and simply did not copy them here - if not I would consider using Option Explicit as you can often run into all sorts of issues without having Option Explicit at the top of your VBA code.
While I agree with the above, it is also important to note that the Delete function will not work if the worksheet's visibility is currently set to xlSheetVeryHidden
I had the same issue and looked at this post for ideas on how to fix it. My issue was resolved by using "Activate" as opposed to "Select" on the line that my code was failing on. So instead of using "mainWS.Select", try using "mainWS.Activate" instead.