How to tell if range is on activesheet or on a fixed/certain sheet? - vba

if I
Dim rng As Range
Set rng = Range("A1")
i know rng is actually ActiveSheet.Range("A1")
then if I
Dim rngsht1 As Range
Set rngsht1 = Worksheets("Sheet1").Range("A1")
then i know rngsht1 is always on Sheet1
So now say I have a range object called "somerange", if I want to know what sheet this range is on I'll probably do this
somerange.worksheet.name
but if it gives me "Sheet1", i can't tell if it's because i have sheet1 active or because somerange is always on sheet1, without having to switch between different sheets and try again.
My question is, is there a simple way to tell whether a range object is on activesheet, or on a fixed/certain sheet? Thanks.
UPDATE: So this question is invalid. Thanks to GSerg I realized that a range object, once created, is ALWAYS on a fixed worksheet which is the worksheet the range object was created on.

Please try to use Is operator (object comparison):
If rangeObject.Worksheet Is ActiveSheet Then
' (... your code ...)
End If

Question the range's Parent
Sub MAIN()
Dim rng As Range
Set rng = Sheets(1).Range("A1")
Call IsItOnTheActiveSheet(rng)
End Sub
Sub IsItOnTheActiveSheet(r As Range)
If r.Parent.Name = ActiveSheet.Name Then
MsgBox "its on the activesheet"
Else
MsgBox "its not on the active sheet"
End If
End Sub

Related

Application.Caller / Storing worksheet name as string

Im trying to store the CurrentWorksheet name in order to reference it in a different Sub routine.
The code I currently have is as follows:
Private Sub InsertNewBill_Click()
Dim rng As Range
Set rng = Worksheets(CurrentWorksheet).Range("A30:L30")
rng.Insert Shift:=xlDown
End Sub
Current Worksheet Function:
Function CurrentWorksheet()
CurrentSheet = Application.Caller.Worksheet.Name
End Function
I need to try to reference the "CurrentSheet" variable in the "InsertNewBill" Sub routine.
The function of this is to insert a new line of cells between "A30:L30" on the currently selected worksheet.
Thanks in advance
I didn't plan to write this as answer, but to explain to Batteredburrito how to deal with objects rather than names:
Option Explicit
Private Sub InsertNewBill_Click()
Dim rng As Range
Set rng = currentWorksheet.Range("A31:AC31")
rng.Insert Shift:=xlDown
End Sub
Current Worksheet Function
Function currentWorksheet() As Worksheet
set currentWorksheet = ActiveSheet
End Function
This is doing exactly the same as your version (so you can stick with that), it's just to show how to deal with objects. But there are situations where it is much better to deal with objects that with name - especially if you are dealing with multiple Workbooks (that might have the same sheet names).
And, of course, in the end you could get rid of the function completely by simply writing
...
Set rng = ActiveSheet.Range("A31:AC31")
...
Thank you all for your help and direction.
I have resolved the issue with the following
Insert new cells between a range of cells on button press:
Private Sub InsertNewBill_Click()
Dim rng As Range
Set rng = Worksheets(CurrentWorksheet).Range("A31:AC31")
rng.Insert Shift:=xlDown
End Sub
Current Worksheet Function:
Function CurrentWorksheet()
CurrentWorksheet = ActiveSheet.Name
End Function

Unable to select worksheet by name

I'm trying to assign the first sheet of the current workbook to sheet object, but I get a Runtime error "91", Object variable or with block variable not set.
Sub Test
Dim InSheet as Worksheet
InSheet = ThisWorkbook.Sheets("Sheet1")
End Sub
However I'm able to loop through the worksheet collection like so
For Each ws in ThisWorkbook.Sheets
Debug.Print ws.Name
Next
Sheets("Sheet1") or Sheets(1) do not work. What am I doing wrong?
Any help would be greatly appreciated.
Thank you
Assuming the workbook has a sheet named "Sheet1", you just need to use Set, and better still, if you know it's a worksheet, and not a chart sheet, use Worksheets:
Sub Test
Dim InSheet as Worksheet
Set InSheet = ThisWorkbook.Worksheets("Sheet1")
End Sub
But you might find it easier to give the sheet a CodeName like InSheet in the properties window, and then you can just refer to it in code, regardless of whether somebody changes its name, like so:
Sub Test
Debug.Print InSheet.Name
End Sub

Ignore blanks in a range

Can some one help with the last bit of this code please, I have a range maximum ("A1:A54") when i set to this range and only (A1:A10) have a cell value which is the name of a sheet in another workbook.
This code is working but returns a
runtime 9 error
I really want to add if blank ignore if I change to range I have set to A1:A10 then no error. I think it might be there is no worksheets in the other workbook this is why I get an error on this loop.
Have looked how to ignore blanks but none of the answers i have found have worked.
I really want a if cell = "" then ignore currently I thought exit sub would work
Sub Iedextraction()
Dim wkb As Excel.Workbook, wkb1 As Excel.Workbook
Dim wks As Excel.Worksheet, wks1 As Excel.Worksheet
Dim cell As Range
Dim rng As Range
Workbooks.Open Filename:= _
"D:\Projects\ASE Templates\ASE Template White Book.xlsx"
Set wkb = Excel.Workbooks("ASE RTU Addressing with Automation.xlsm")
Set wks = wkb.Worksheets("Tab Names from White book")
Set wkb1 = Excel.Workbooks("ASE Template White Book.xlsx")
Set rng = wks.Range("A1:A54")
For Each cell In rng
wkb1.Sheets(cell.Value).Copy After:=Workbooks_
("ASE RTU Addressing with Automation.xlsm").Sheets(4)
If cell = "" Then Exit Sub
Next
' On Error GoTo 0
End Sub
Add conditional instruction:
If cl <> "" Then wkb1.Sheets(cell.Value).Copy After:=Workbooks _
("ASE RTU Addressing with Automation.xlsm").Sheets(4)
And remove:
If cell = "" Then Exit Sub
Your error occurs most probably because you try to copy before you do the check. So, at the end, you try to get a sheet with no name. :)
It is better practice to use dynamic ranges since it's likely going to change at some point in the future. There are multiple ways of doing this, but my go to method is something like this:
Dim rn As Range
Set rn = Range(Range("A1"), Range("A1").End(xlDown))
So your issue would be resolved (assuming the blank cells are truly empty) and you will not have to test for blank cells.
Regardless, you should mark one of the above answers are correct if they fixed your issue.

Private Sub User-Defined Type Not Defined Range Sheet

First post. I have the relatively simple code below and am getting a
User-defined type not defined
error. I know that the stand alone code works when I place it into one Sub but for various reasons I want to split it out so that in my larger workbook I can just call on the second sub rather than having to copy and paste the whole loop multiple times. The purpose of the code is to autosize the specified range in excel.
Sub letsGo()
Dim rng As Range
Dim sht As Worksheet
Set rng = ThisWorkbook.Sheets("Sheet1").Range("Range1")
Set sht = ThisWorkbook.Sheets("Sheet1")
Call whyDoesntThisWork(sht, rng)
End Sub
Private Sub whyDoesntThisWork(rangeSheet As Sheet, rangeTable As Range)
Dim Col As Range
Dim reSize As Range
For Each Col In rangeTable.Columns
If Col.Hidden = False Then
Set reSize = rangeSheet.Range(rangeSheet.Cells(rangeTable.Row, Col.Column), rangeSheet.Cells(rangeTable.Rows.Count, Col.Column)) reSize.Columns.autoFit
End If
Next Col
End Sub
You have two different data types:
Private Sub whyDoesntThisWork(rangeSheet As Sheet, rangeTable As Range)
rangeSheet is a Sheet, but when you call it, you pass:
Call whyDoesntThisWork(sht, rng)
sht is of type WorkSheet
That's your inconsistency. I recommend you change your definition to:
Private Sub whyDoesntThisWork(rangeSheet As WorkSheet, rangeTable As Range)
Change rangeSheet As Sheet to rangeSheet As Worksheet

VBA Select method errors

I am new to VBA and basically trying to write my first macro. It is meant to copy entries from one workbook to another omitting repeating values. I have the following code:
Dim s As String
Do While IsEmpty(ActiveCell) = False
If ActiveCell.Value <> s Then
s = ActiveCell.Value
ActiveCell.Offset(1, 0).Select
Windows("Main.xlsm").ActiveCell.Value = s
Windows("Main.xlsm").ActiveCell.Offset(1, 1).Select
Else
ActiveCell.Offset(1, 0).Select
End If
Loop
It gives me Runtime error 1004 for this line:
Windows("Main.xlsm").ActiveCell.Offset(1, 1).Select
Which means that method Select didn't work properly. (I have "Main.xlsm" opened but not active and a cell is selected.)
I searched similar questions and found that it may be because I haven't selected a sheet.
But somehow this line works:
Windows("Main.xlsm").ActiveCell.Value = s
And I can see that cell changed in workbook "Main.xlsm". So, I assume that Windows("Main.xlsm").ActiveCell does create a Range object.
Then why does the error happen? And what is the correct way to write this?
Also I tried changing my code to:
Windows("Main.xlsm").ActiveSheet.ActiveCell.Value = s
Windows("Main.xlsm").ActiveSheet.ActiveCell.Offset(1, 1).Select
Which gave me: "Runtime Error 438 Object doesn't support this property or method". Why is that? What's incorrect here?
And to:
Windows("Main.xlsm").Sheets("Name").ActiveCell.Value = s
Windows("Main.xlsm").Sheets("Name").ActiveCell.Offset(1, 1).Select
Which resulted the same way. And I still don't understand why two last don't work.
This is my first post here so if my editing or anything else is wrong please correct me.
Thanks!
Using ActiveCell, Select etc is not a good idea. Browse through SO Excel tag and you will find many answers advocating against it, many with good explanations why. For one of mine see this question
Instead, declare Range and Worksheet variables and assign these to your ranges and sheets
Dim wbSource as WorkBook
Dim wsSource as WorkSheet
Set wbSource = Application.Workbooks("Main.xlsm")
Set wsSource = wbSource.Worksheets("Name")
To use the workbook the VBA is in, use the ThisWorkbook object
If you want to start with the active sheet, it usuallu OK to use
Dim sh as Worksheet
Set sh = ActiveSheet
To work with a range, use something like
Dim rng as Range
' Set to a specific range
Set rng = Range sh.Range("A1:D10")
' or
With sh
Set rng = .Range(.Cells(1,1), .Cells(10,4))
End With
' Set to all used cells in a column
With sh
Set rng = .Range(.Cells(1,1), .Cells(.Rows.Count,1).End(xlUp))
End With
' Adjust rng
Set rng = rng.Offset(1,0)
Set rng = rng.Resize(10,1)
So, to refactor your code fragment
Dim s As String
Dim rng as Range, cl as Range
Dim shSource as Worksheet
Dim rngDestination as Range
Set shSource = Application.Workbooks("Main.xlsm").Worksheets("SheetName")
Set rngDestination = shSource.Range("A1") ' Change to whatever you need here
Set rng = ActiveCell ' if you must!
' Just in case only one cell entry exists, avoid selecting down to bottom of sheet
If Not IsEmpty(rng.Offset(1,0)) Then
Set rng = Range(rng, rng.End(xlDown)) ' unqualified Range (ie no sh. part) refers to the active sheet
End IF
For Each cl In rng
If cl.Value <> s Then
s = cl.Value
rngDestination.Value = s
Set rngDestination = rngDestination.Offset(1, 1) ' should this be .Offset(1, 0) ?
End If
Next