Code giving Object Block Variable Error - excel

I have a small userform with one combo box and 2 text boxes and submit button.
While pressing the submit button, i am getting the object variable not set error.
Here is my code:
Private Sub CommandButton1_Click()
Dim ws As Worksheet, tbl As ListObject, row As ListRow
Set ws = Sheets("Create Account Heads")
Set tbl = ws.ListObjects(Me.TextBox2.Value)
Dim intValueToFind As String, rng As Range
Set rng = tbl.ListColumns(1).DataBodyRange
intValueToFind = LCase(Me.TextBox3.Value)
If rng <> 0 Then
For Each rng In rng
If LCase(rng.Value) = intValueToFind Then
MsgBox ("Account Head with this Name Already Exists.")
Exit Sub
End If
Next rng
Else
'Unprotect the Worksheet
ws.Unprotect Password:="google"
End if
End Sub
i am getting the error in "If rng <> 0 Then" line.
Kindly review and advise to overcome this issue.
Thanks
Salman

Replace your line code of:
If rng <> 0 Then
with:
If Not rng Is Nothing Then

Related

Excel VBA select mulptiple cells based on selection

I would like to select multiple cells based on selection.
And here is my code:
Private Sub CommandButton1_Click()
Selection.EntireRow.Select
End Sub
I want to select the first four columns of rows in multiple cells, instead of the whole rows. How to achieve it?
this is my Excel worksheet
Select Rows of Non-Contiguous Range
Copy the codes into a standard module e.g. Module1.
In your command button click event use either of the procedure names in the following way:
Private Sub CommandButton1_Click()
selectRowsOfListObject
End Sub
or
Private Sub CommandButton1_Click()
selectRowsOfFirstFourColumns
End Sub
The first procedure will select only the rows of the selected cells in the first (structured) table in the ActiveSheet. Any cells outside the data of the table (DataBodyRange) will be ignored.
The second procedure will select all the row ranges of the selected cells in the first four columns, in the first four columns of the ActiveSheet. Any cells selected outside of the first four columns will be ignored
Each or both of the codes can be used with command buttons on any worksheet when they will refer to the worksheet 'containing' the command button.
If you want a command button on another worksheet to always refer to the first, you will rather have to create a reference to the first worksheet:
Instead of
Set ws = ActiveSheet
use e.g.
Set ws = wb.Worksheets("Sheet1")
To better understand the differences, you could add another command button for the second code and then test each of them.
The Code
Option Explicit
Sub selectRowsOfListObject()
Dim wb As Workbook
Set wb = ThisWorkbook
Dim ws As Worksheet
Set ws = ActiveSheet
Dim tbl As ListObject
Set tbl = ws.ListObjects(1)
If Selection.Worksheet.Name = ws.Name Then
If TypeName(Selection) = "Range" Then
Dim rng As Range
Set rng = Intersect(Selection, tbl.DataBodyRange)
If Not rng Is Nothing Then
Set rng = Intersect(rng.Rows.EntireRow, tbl.DataBodyRange.Rows)
End If
If Not rng Is Nothing Then
rng.Select
End If
End If
End If
End Sub
Sub selectRowsOfFirstFourColumns()
Dim wb As Workbook
Set wb = ThisWorkbook
Dim ws As Worksheet
Set ws = ActiveSheet
If Selection.Worksheet.Name = ws.Name Then
If TypeName(Selection) = "Range" Then
Dim rng As Range
Set rng = Intersect(Selection.Rows.EntireRow, _
ws.Columns(1).Resize(, 4))
If Not rng Is Nothing Then
rng.Select
End If
End If
End If
End Sub
Check this code:
Option Explicit
Sub Rows_Selection()
Dim rng As Range
Dim active_cells_adress, row_no As Variant
Dim final_selection_adress As String
Dim rng1 As String
Dim i As Integer
Selection.EntireRow.Select
Set rng = Selection
rng1 = rng.Address
final_selection_adress = ""
active_cells_adress = Split(rng1, "$")
For i = 2 To UBound(active_cells_adress)
row_no = Split(active_cells_adress(i), ",")
final_selection_adress = final_selection_adress + "A" & row_no(0) & ": D" & row_no(0) + ","
i = i + 1
Next
final_selection_adress = Left(final_selection_adress, Len(final_selection_adress) - 1)
Range(final_selection_adress).Select
End Sub

VBA user defined range and check if it is empty

I have been struggling with this for over an hour. I need to write a VBA code where the user selects a range and then I check if this selected range is empty before I go and do anything else.
This is what I have so far:
Sub test()
Set rng= Application.InputBox("Select the range of the raw data please", Type:=8)
If Application.WorksheetFunction.CountA(Range(rng)) > 0 Then
MsgBox "do this, this and that!"
End If
End Sub
When I run this I get a "Method Range of object_Global failed". I know it lets the user select the range just fine but the Range(rng) is not working right. Any help would be appreciated!
Your problem is that your variable rng is a range and you're trying to wrap that in a range, which is why it's throwing an error. Try this instead.
Sub test()
Dim rng As Range
Set rng = Application.InputBox("Select the range of the raw data please", Type:=8)
If Application.WorksheetFunction.CountA(rng) > 0 Then
MsgBox "do this, this and that!"
End If
End Sub
Just some code
Sub main()
Dim sentRange As Range
Set sentRange = Application.InputBox("Select the range of the raw data please", Type:=8)
If isRangeEmpty(sentRange) = False Then
MsgBox "Range is not empty."
Else
MsgBox "Good to go!"
End If
End Sub
Function isRangeEmpty(ByRef myRange As Range) As Boolean
Dim rngLoop As Range
Dim rangeEmpty As Boolean
For Each rngLoop In myRange
If rngLoop.Value = Empty Then
'All Good
isRangeEmpty = True
Else
'Need to exit
isRangeEmpty = False
Exit For
End If
Next rngLoop
End Function
If you are only acting on the instance of data being present then something like below will work. I would also adding Option Explicit to the top of your code and declare all variables.
Sub How()
Dim rng As Range
Set rng = Application.InputBox("Select Target Range", Type:=8)
If Application.WorksheetFunction.CountA(rng) <> 0 Then
'Actions
End If
End Sub

How to set a range using the find function

I have a stylized spreadsheet with formatted cells for users to input data. I am trying to create a macro for use with a button to clear all of the input cells at once. However, I am struggling with the "find" and "findformat" functions.
To make it simple, in this code I am just looking for cells that say "Retail". When I run the code, the value of myRange is always Nothing even though there is clearly a cell in the spreadsheet that has the value "Retail". Any ideas why the range is Nothing?
Public Sub reset()
'reset all input fields to no value
msg = MsgBox("Are you sure you want to delete all data and reset all files to original state?", vbYesNoCancel, "***Warning***")
If msg = vbYes Then
Dim inputCell As Long
Dim noteCell As Long
inputCell = RGB(255, 204, 153)
noteCell = RGB(255, 255, 204)
Dim myRange As Range
Dim mySheet As Worksheet
Dim shp As Shape
Dim sht As Worksheet
Dim objXL As Object
Dim wb As Workbook
Dim pathName, name, myLink As String
Set sht = ActiveSheet
Set wb = ActiveWorkbook
pathName = wb.FullName
name = wb.name
For Each shp In sht.Shapes
If shp.Type = msoGroup Then
For i = 1 To shp.GroupItems.Count
If shp.GroupItems(i).Type = msoEmbeddedOLEObject Then
shp.GroupItems(i).Select
shp.GroupItems(i).OLEFormat.Activate
Set wb = ActiveWorkbook
If Not IsEmpty(wb.LinkSources(xlExcelLinks)) Then
For Each link In wb.LinkSources(xlExcelLinks)
On Error Resume Next
wb.ChangeLink name:=link, newName:=pathName, Type:=xlLinkTypeExcelLinks
Next link
End If
For Each mySheet In ActiveWorkbook.Worksheets
With Application.FindFormat.Interior.Color = inputCell
myRange = mySheet.Cells.Find(what:="Retail") ', searchformat:=True)
myRange.ClearContents
End With
Next mySheet
wb.Close (False)
End If
Next i
End If
Next shp
End If
End Sub
I refer to the FindFormat documentation for some example:
https://msdn.microsoft.com/en-us/library/office/ff838023.aspx
And modify your code thusly:
With Application.FindFormat
.Interior.Color = inputCell
Do
Set myRange = mySheet.Cells.Find(what:="Retail", SearchFormat:=True)
If myRange Is Nothing Then myRange.ClearContents
Loop While Not myRange Is Nothing
End With
NOTE: You should be using the Set keyword when assigning to a range object myRange. Also, your improper use of On Error Resume Next may be masking additional errors which are adversely impacting the results of this function. You can rectify the latter issue like so:
If Not IsEmpty(wb.LinkSources(xlExcelLinks)) Then
For Each link In wb.LinkSources(xlExcelLinks)
On Error Resume Next
wb.ChangeLink name:=link, newName:=pathName, Type:=xlLinkTypeExcelLinks
On Error GoTo 0 '### RESUME NORMAL ERROR HANDLING
Next link
End If
I changed my code as follows and now it works exactly as I wanted:
For Each mySheet In ActiveWorkbook.Worksheets
With Application.FindFormat
.Interior.Color = inputCell
Do
On Error GoTo handler:
Set myRange = mySheet.Cells.Find(what:="?*", searchformat:=True).MergeArea
If Not (myRange Is Nothing) Then
myRange.ClearContents
End If
Loop While Not (myRange Is Nothing)
.Interior.Color = noteCell
Do
On Error GoTo handler:
Set myRange = mySheet.Cells.Find(what:="?*", searchformat:=True).MergeArea
If Not (myRange Is Nothing) Then
myRange.ClearContents
End If
Loop While Not (myRange Is Nothing)
handler:
Set myRange = Nothing
Resume Next
End With
Next mySheet
I'm just not sure if this kind of error handling is the best way to deal with the problem, and I don't understand why an error occurs in the first place. So if anyone has a thought on this, I would appreciate it. If not, I'm just happy it works now.

Error 91 setting range of worksheet variable

I'm at a loss as to why it seems that I can store a range value in the range property of a worksheet variable but not in a range variable. I got error 91 every time I tried to run this code:
Dim ws As Worksheet, rng As Range
Set ws = Worksheets.Add
ws.name = "Potato"
rng = ws.Range("A1:K1")
rng.PasteSpecial
I was able to run the program successfully by replacing the last 2 lines with:
ws.Range("A1:K1").PasteSpecial
This works, even though it clutters other parts of my code. But I can't understand for the life of me what the problem was with using the range variable was.
I would appreciate any clarification anyone can provide.
You have to use Set with object variables:
Set rng = ws.Range("A1:K1")
Here is added code that will make sure there won't be an error if you already have a sheet named "Potato"
Code to make sure Sheet("Potato") doesn't already exist.
Sub Button1_Click()
Dim ws As Worksheet, rng As Range, cRng As Range
Dim worksh As Integer
Dim worksheetexists As Boolean
Dim s As String
s = "Potato"
Set cRng = ActiveSheet.Range("A1:K1")
worksh = Application.Sheets.Count
worksheetexists = False
For x = 1 To worksh
If Worksheets(x).Name = s Then
worksheetexists = True
MsgBox s & ", already Exists"
Exit For
End If
Next x
If worksheetexists = False Then
Set ws = Worksheets.Add()
ws.Name = s
Set rng = ws.Range("A1:K1")
cRng.Copy
rng.PasteSpecial Paste:=xlPasteAll
Application.CutCopyMode = 0
End If
End Sub

Define Cell Location Variable in Excel

I'm looking for a way to, instead of typing "ActiveCell.OffSet(1,1) over and over again in my vba code, define that as a variable, "x" and use that instead.
I have to use the dim command to do this but I"m not sure what the data type would be.
Suggestions?
When I test it using the code below I get Runtime Error 1004.
Private Sub CommandButton1_Click()
Dim i As Range
Set i = ActiveCell
ActiveSheet.Range(ActiveSheet.Range(i), ActiveSheet.Range(i).End(xlUp)).Select
End Sub
In response to your edit
Avoid the use of .Select/Activate and fully qualify your objects. INTERESTING READ
Your code can be written as
Private Sub CommandButton1_Click()
Dim ws As Worksheet
Dim rng1 As Range, rng2 As Range
'~~> Change as applicable
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
Set rng1 = ws.Range("A10")
Set rng2 = .Range(rng1, rng1.End(xlUp))
With rng2
Debug.Print .Address
'
'~~> Do something with the range
'
End With
End With
End Sub
If you still want to know what was wrong with your code then see this.
You have already defined your range. You do not need to add ActiveSheet.Range() again. Your code can be written as
Private Sub CommandButton1_Click()
Dim i As Range
Set i = ActiveCell
ActiveSheet.Range(i, i.End(xlUp)).Select
End Sub
EDIT
Followup from comments
Was ActiveSheet.Range() actually problematic or just redundant? – user3033634 14 mins ago
It is problematic. The default property of a range object is .Value
Consider this example which will explain what went wrong with your code
Sub Sample()
Dim ws As Worksheet
Dim rng As Range
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
Set rng = .Range("A1")
rng.Value = "Blah"
MsgBox rng '<~~ This will give you "Blah"
MsgBox rng.Value '<~~ This will give you "Blah"
MsgBox rng.Address '<~~ This will give you "$A$1"
MsgBox ws.Range(rng) '<~~ This will give you an error
'~~> Why? Becuase the above is evaluated to
'MsgBox ws.Range("Blah")
MsgBox ws.Range(rng.Address) '<~~ This will give you "Blah"
End With
End Sub
Dim x As Range
Set x = ActiveCell.OffSet(1,1)
EDIT: in response to your comment:
Private Sub CommandButton1_Click()
Dim i As Range
Set i = ActiveCell
ActiveSheet.Range(i, i.End(xlUp)).Select
End Sub

Resources