VBA Run-time error 9 With Sheet - vba

So here I have VBA code that is a part of my function, yet whenever I run it, I get the following error:
Run-Time error '9': Subscript out of range
The actual worksheet exists. In the vba editor on the side panel, it appears as Sheet2(Data_Sheet). In the details in that panel, it shows (Name) as being Sheet 11 and Name as being Data_Sheet. Dos anybody know a possible source of this error? My code is below:
With Sheets("Data_Sheet")
'this searches just row 1
Set header_cell_1 = .Rows(1).Find(What:="One", lookat:=xlWhole, MatchCase:=False, searchformat:=False)
Set header_cell_2 = .Rows(1).Find(What:="Two", lookat:=xlWhole, MatchCase:=False, searchformat:=False)
Set header_cell_3 = .Rows(1).Find(What:="Three", lookat:=xlWhole, MatchCase:=False, searchformat:=False)
Set header_cell_4 = .Rows(1).Find(What:="Four", lookat:=xlWhole, MatchCase:=False, searchformat:=False)
Set header_cell_5 = .Rows(1).Find(What:="Five", lookat:=xlWhole, MatchCase:=False, searchformat:=False)
Set header_cell_6 = .Rows(1).Find(What:="Six", lookat:=xlWhole, MatchCase:=False, searchformat:=False)
Set header_cell_7 = .Rows(1).Find(What:="Seven", lookat:=xlWhole, MatchCase:=False, searchformat:=False)
col_1 = header_cell_1.Column
col_2 = header_cell_2.Column
col_3 = header_cell_3.Column
col_4 = header_cell_4.Column
col_5 = header_cell_5.Column
col_6 = header_cell_6.Column
col_7 = header_cell_7.Column
End With

As from comments, the macro is running from the PERSONAL.XSLB workbook so it's trying to finding the Sheets("Data_sheet") in it, and clearly not finding because it is into another workbook --> Subscript out of range.
To fix, always use full references of the Object you work with:
With Workbooks("myWorkbook.xlsm").Sheets("Data_sheet") '<-- explicitly saying in which workbook it must look for the sheet
End With
Alternatively, remember that:
ThisWorkbook references the workbook the code runs from. In your case, it would reference the PERSONAL.XLSB;
ActiveWorkbook references the currently active workbook. Very risky to use (usually, you should know which workbook you want to target). But there might be some cases in which you want the code to intentionally running on the active workbook (see the example of an add-in: the code runs from the add-in, but you want the add-in to run on the workbook from which is used).
WARNING:
A common error is not to use any reference, like in your case:
With Sheets("Data_Sheet") '<-- of which workbook?
In that case, VBA answers the question itself with ActiveWorkbook, which is the default object. Only if you explicitely want to run from the ActiveWorkbook you should leave it like that; otherwise, always reference the object to avoid any bug related to this.

Related

Run time error 91, Object variable or with block variable not set, lastrow [duplicate]

What I want:
I've got a lot of sheets whith different devices. Let's call one of these sheets "WS1".
And I've got a seperate sheet with all existing devices and the appropriate OS next to it. This one we call "list".
Now I want the other sheets (e.g. the "WS1") to check the "list", find the right device, and copy the right OS into the WS1-sheet.
the manual way would be:
select cell "C3" of WS1 and copy it.
open the "list"-Sheet and find the copied entry
select the cell left to the found entry and copy it
open the WS1 again, select the left cell right next to the active cell and paste the new clipboard (which contains the OS)
select the next cell which is under and on the right side of the active cell.
loop until every device in WS1 is filled with an OS
What I've got so far:
Dim DataObj As New MSForms.DataObject
Dim strCliBoa As String
'strCliBoa = DataObj.GetText
DataObj.GetFromClipboard
Range("C3").Select
Selection.Copy
strCliBoa = DataObj.GetText
Sheets("list").Select
Range("A1").Select
Cells.Find(What:=strCliBoa, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False).Activate
ActiveCell.Offset(0, -1).Select
Selection.Copy
strCliBoa = DataObj.GetText
Sheets("WS1").Select
ActiveCell.Offset(0, -1).Select
ActiveSheet.Paste
ActiveCell.Offset(1, 1).Select
My issue:
"Runtime Error 91: Object variable or with block variable not set"
and it marks the cells.find-method.
Can someone tell me what I'm doing wrong?^^
Thanks in advance!
(oh, almost forgot: I'm using ms excel 2010 on Win7)
If the string you're looking for isn't found you'll get that error. The find function returns "Nothing" if nothing is found
Dim r As Range
Set r = Cells.find(What:=strCliBoa, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=True, SearchFormat:=False)
If r Is Nothing Then
'handle error
Else
'fill in your code
End If
I'll provide you an answer using the VLOOKUP() function. So Sheet1 contains several devices and I need to find the correct OS. Sheet2 contains the matching between device and OS.
On Sheet1 enter this formula in the cell next to device and pull it down (of course edit to your specific needs).
=VLOOKUP(A2;Sheet2!$A$1:$B$20;2;0)
EDIT: the VLOOKUP function will only work if the OS is in second column. Either switch around the columns or use a helper column at the end to contain the OS.
In the sheet where you have the Device name (WS1) put formula:
=INDEX(List!$A$2:$B$10;MATCH('WS1'!C3;List!$B$2:$B$10;0);1)
Where :
List!$A$2:$B$10 is a range where you have the Devices + OS in the list
'WS1'!C3 is the Device you want to search for in the list ("WS1" in your case)
List!$B$2:$B$10 is the column on Sheet List, where the devices are listed.
Edit 1 - VBA code
If you want to use VBA then use this :
Sub FindDevicePasteOS()
'Find corresponding OS for the device
Dim intRow As Integer
Dim wsht As Worksheet
For Each wsht In Worksheets
If wsht.Name <> "List" Then 'add more sheets you want to exclude using OR (e.g. ... Or wsht.Name <> "Cover Sheet" Then)
For intRow = 3 To wsht.Cells(Rows.Count, 3).End(xlUp).Row 'presuming there is nothing else in the column C below the devices
If Not Worksheets("List").Cells.Find(what:=wsht.Cells(intRow, 3)) Is Nothing Then
wsht.Cells(intRow, 2) = Worksheets("List").Cells.Find(what:=wsht.Cells(intRow, 3)).Offset(0, -1)
End If
Next intRow
End If
Next wsht
End Sub
So I used a psuedo solution where I added the If x is nothing block to the code to skip over the err'd pieces. I was able to process about 80% of the data which is good for me. I still can't understand why Find would return nothing.
Another interesting and maybe related problem occurred in a different computer running the same macro - after I ran into this problem a few times, my computer gave me a blue screen with a 'thread stuck in driver' message. Could they be related? Excel processing to much to fast and get's mixed in the thread processing?
Food for though, I dunno why the find won't just work every-time.
In Sobigen post I had to switch the part LookAt:=xlPart to LookAt:=xlWhole to get it to work because If r Is Nothing Then was throwing an error when it found partial matches. Other than that the code worked great thanks!

Return cell row and column of a cell after using find

I am searching for a VBA command that in combination with find() (or similar) returns the address of the found cell in a fixed column.
Due to the programm, the value I am searching for exists only once, but apparently I could only return its value, not its location.
Set Cell = Selection.Find(What:=Choice, LookIn:=xlFormulas,_
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext,_
MatchCase:=False, SearchFormat:=False)
It is probably an easy question, but help is much appreciated!
Write after your code:
debug.print cell.row
debug.print cell.column

Creating VBA code to reference cell text and create a dynamic Find & Replace

I work with multiple excel spreadsheets that require monthly updates for month end financial closing. I need to change references to outside workbooks so that it pulls in data from the current months file.
For example changing
"C:\Desktop\Folder\June"
to
"C:\Desktop\Folder\July"
I want to be able to enter the two months into specific cells in the worksheet and then run a VBA script to auto update the references throughout the workbook. I can record a "macro" for the Find & Replace function, but I can't figure out how to point the "Find" and "Replace" variables to the specific cells where I store the month values.
Here is the current code I have for conducting find and replace:
ActiveCell.Replace What:="Jun", Replacement:="Jul", LookAt:=xlPart, _
SearchOrder:=xlByColumns, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Replace the literal text strings of "Jun" and "Jul" with a cell reference. For this, you can use Range("A1"). Of course, you would put in the actual range.
ActiveCell.Replace What:=Range("A1"), Replacement:=Range("B1"),LookAt:=xlPart, _
SearchOrder:=xlByColumns, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False`
What you should do is give those cells names then you can reference the cells
Range("find1").Select
ActiveCell.FormulaR1C1 = "July"
Range("find2").Select
ActiveCell.FormulaR1C1 = "July"

Run an Excel VBA script on only the active worksheet and not the entire book?

I am using a VBA script to essentially find/replace. Right now when I run the VBA script it applies to all open sheets in the workbook. I wish for the VBA script to only apply in the active sheet and not touch the rest.
Here is my current macro code:
Sub ReplaceCC()
'
' ReplaceCC Macro
' Add CC to Distributor, Reseller, Government and Retail.
'
'
Range("A1").Select
Cells.Replace What:="Distributor", Replacement:="DistributorCC", LookAt:= _
xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Cells.Replace What:="Reseller", Replacement:="ResellerCC", LookAt:=xlPart _
, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Cells.Replace What:="Government", Replacement:="GovernmentCC", LookAt:= _
xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
Cells.Replace What:="Retail", Replacement:="RetailCC", LookAt:=xlPart, _
SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, _
ReplaceFormat:=False
End Sub
Here is the entire VBA script with all subs.
I got the same problem. It depends of the Find/Replace history: if in the previous manual use of Find/Replace, you specified "Options > Search in Workbook", your macro will apply to all sheets. Otherwise, with the default "In Sheet", the macro will stay in the original Worksheet. I still don't know how to fix that from within the macro, though.
Interesting question. I believe that you could do what you're trying to do by simply placing "ActiveSheet" before each object reference in your code.
For example: Instead of Range("A1").Select use ActiveSheet.Range("A1").select
If you set up your code like this, whenever you execute, it should carry out its actions on the worksheet you currently have active.
EDIT: You should check to see which module you have this code placed in. If it is in an inserted module, I think you should be fine. On the other hand, if you've inserted it in one of the sheet modules it will only modify the sheet it is attached to. If you insert ActiveSheet before your cell references and the rest it will still modify the active sheet instead of the sheet the code is attached to.
It seems the macro was not recognizing the active sheet properly since the sheets were copies of each other. If you copy the content on Sheet 1 and create a new sheet then paste the content on it this will work. Each sheet needed to be unique and not just a copy of the original.
This is due to a VBA bug. When you use "Find" in VBA, the parameter "LookAt:=xlPart" or "LookAt:=xlWhole" works as expected. But when you use "Replace", the coded parameter is ignored and the replace uses the last MANUAL setting for its scope. The workaround is to do a "Find" operation right before the "Replace" operation, since "Find" uses the coded "LookAt" scope (thereby making the "Find"'s scope the last setting used, so the "Replace" will then use the scope coded into the "Find").
Solution from http://www.vbaexpress.com/forum/showthread.php?11444-Solved-Replace-in-a-sheet-and-not-the-entire-workbook
Dim dummy As Range
Set dummy = Worksheets(1).Range("A1:A1").Find("Dummy", LookIn:=xlValues)
Then you can post REPLACE functions underneath these lines of codes

VBA Referring to a cell using Sheet Name not working properly

Summary: I am writing a macro that takes names from many different sheets in an excel file and compiles them together on a "master list", but I'm having trouble with referencing a cell on another sheet.
The Problem: When I refer to a specific cell using the sheet name as reference with Sheets("MasterList").ActiveCell.Offset(0, 1), nothing gets picked up. However, when I remove Sheets("MasterList") the macro works fine (the macro is currently on "MasterList" at the time which is the only way this would work). Also, the spelling for the name of the sheet was correct in my code.
Question: Why is this happening? The logic behind the code seems sound, and I'm spelling my sheet name correctly.
Code:
Do
If Sheets("MasterList").ActiveCell.Offset(0, 1) = firstName Then 'IF FIRST AND LAST NAMES MATCH, EXIT THE CHECK
Exit Do
End If
On Error Resume Next
Cells.Find(What:=lastName, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
Loop Until Err.Number > 0
ActiveCell is a property of the Application object, not a Sheet.
There is only one ActiveCell, and it is the active cell on the currently active sheet.
It's not entirely clear what you are trying to do. But in general you should avoid Select and Activate with this sort of code. Use instead somthing like:
Dim wsMasterList as Worksheet
Set wsMasterList = Thisworkbook.WorkSheets("MasterList") ' assuming the vba code is in the workbook containing MasterList
To track the last used cell in MasterList use a variable like
Dim rMasterList as Range
Set rMasterList = wsMasterList.Cells( ... ' Specify the cell you want
Then use rMasterList.Offset(0, 1) to refer to cells relative to that cell
Searching on MasterList use:
Dim cl as Range
Set cl = wsMasterList.UsedRange.Find( ... )
If Not cl Is Nothing Then
' cl will be Nothing if the search term is not found
' ...