How to pass a column of a selected range - vba

I did a little research and I found my question. The problem is it is written for some language called C that I am not familiar with. Not that I am all that familiar with VBA either but that is what I am working in and doing a very nice job of screwing things up. So in an effort to thwart my abilities to screw things up and instead make things work, how do I pass a sub range or column from a user selected column?
so in my example code I was trying to pass the entire first column of whatever was selected. Lets say user range was B34:D40, I want to pass B34:B40 such that arrange is B34:B40.
Sub initialsub (userrange as range)
Call secondfunction (userrange([],1)
end sub
----------------------------------------------------------------
function secondfunction (arrange as range) as long
some function that counts a variety of things in a single column
secondfunction = 45
end function

One way:
Sub dural()
Dim FirstColumn As Range
Set FirstColumn = Intersect(Selection(1).EntireColumn, Selection)
MsgBox FirstColumn.Address
End Sub
Also:
Sub dural()
MsgBox Selection.Columns(1).Address
End Sub
seems to do the trick.

Related

Copy/Paste - Subscript out of range error

I searched and did not find an exact duplicate of my question. Maybe it's out there but I did not find it.
I and using the following simple code to copy a range from one sheet to a range on another sheet.
Sub ApacheGetCopyOfLogList()
Sheets("Sheet8").Range("B5:B92").Copy _
Destination:=Sheets("Sheet10").Range("B5")
End Sub
I have also tried:
Sub ApacheGetCopyOfLogList()
Sheets("Sheet8").Range("B5:B92").Copy _
Destination:=Sheets("Sheet10").Range("B5:92")
End Sub
--thinking that destination range may need to be the same size, but that is not true. I still get the same error.
It has to be something about how I am referring to the different worksheets. I say this since the following code always works without fail:
Sub Something
Range("L5:M1000").Copy _
Destination:=Range("A5")
End Sub
I just can't see what I am getting wrong. It's probably super simple! But it's the end of a long day and I need some guidance. Thanks in advance.
If you want to use worksheet codenames instead of worksheet names the syntax is different.
Sub ApacheGetCopyOfLogList()
Sheet8.Range("B5:B92").Copy _
Destination:=Sheet10.Range("B5")
End Sub

Specify a certain column in a range?

So sorry if this is really obvious, but I'm having some trouble connecting two pieces of information.
I have a one-cell range (for example, like A1) and a second, larger range (such as A1:C223). I want to be able to write some code that will make a new range using the column of the one-cell, and the number of rows of the larger range (so in this example, it would end up being A1:A223).
I want to use this specifically to create a loop later, but I'm having trouble creating this range first. Any help would be appreciated.
I think I understand what you want. See if this works:
Sub test()
Dim rangeA As Range, rangeB As Range, combRange As Range
Set rangeA = Range("A1")
Set rangeB = Range("A1:C223")
Set combRange = Range(Cells(rangeB.Rows(1).Row, rangeA.Column), _
Cells(rangeB(rangeB.Rows.Count, 1)(1).Row, rangeA.Column))
Debug.Print combRange.address
End Sub
Edit: This is a little too much perhaps, it looks like #SiddharthRout has a great solution too in the comments :D

User-defined Function to change color of a cell

I've seen many users asking questions trying to change the colors of cells using User-defined functions. I was always under the impression that it was not possible to do so. My understanding was that a user-defined function cannot change any properties of a cell except the value of the cell that contains the formula. Subs are what change cells themselves.
However, when playing around with some code to test this, I found that it's not always the case.
Using the simple code:
Function ColorCell(rng As Range)
If rng.Value = 1 Then
ColorCell = False
Else
ColorCell = True
rng.Interior.ColorIndex = 3
End If
End Function
If I enter the function into a cell, I achieve expected results, no cells change colors. However, if I use the Formulas > Insert Function button and navigate to my formula to insert it this way, it does color the targeted cells.
How is this possible, and why did the function behave differently when entered in different ways?
EDIT: this was tested using Excel 2007
use this code...just replace sheet name and try
Sheets("sheet_name").range(j:j).clear
for j=2 to 15
if Sheets("sheet_name").Cells(j, 1).value=1 then
else
Sheets("sheet_name").Cells(j, 1).Interior.ColorIndex = 3
next j
As we all find out sooner or later, in user functions you can't access subs that change things in your spreadsheet directly.
But try this:
Dim ColorMeTarget As Range, ColorMeVal As Long
Public Function ColorMe(ByVal TargetRange As Range, ByVal ColVal As Long)
Set ColorMeTarget = TargetRange
ColorMeVal = ColVal
ColorMe = ColVal
End Function
Public Sub ColorMeSub()
Application.OnTime Now + TimeValue("00:00:05"), "ColorMeSub"
If ColorMeTarget.Interior.Color <> ColorMeVal Then ColorMeTarget.Interior.Color = ColorMeVal
End Sub
If you run the sub first, it will constantly scan the static variables ColorMeTarget and ColorMeVal to see if there is a change. The function ColorMe will set these values. Some additional code is needed in case ColorMeTarget is not yet initialized.
If you get smarter, you could have the function first check to see if there is indeed a change and add the new coloring requests to a stack. Your reoccurring sub can then 'catch up', especially if you have many functions like this.
You can then even have all kinds of additional controls added to your function/macro--EVEN STUFF NOT COVERED BY THE LATEST VERSIONS OF 'CONDITIONAL FORMATING'!!! YAY!!!!
Something to try: In some of my automated macros, I am able to set OnTime through a function but cannot make it work here. It would be cleaner to have the function set the OnTime and not have a reoccuring sub that needs initializing.
I use Worksheet_Change event to detect value change in working range. Example.I want to do something when range A1:A5 has been change. I use below event.
Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range(<Your working range>)) Is Nothing Then 'Define range that you want to do
'Statement here
...
End If
End Sub
When the range value has been change. It will execute your code.
And other way. Use Conditional Formatting.
could also try the non-script method of auto-coloring a cell based on the condition of the cell (aka Conditional Formatting):

Excel macro select two ranges and compare

This is a question that was asked to me in an interview. I have a excel list. It is copied to another location and then by mistake a row in the new location gets deleted.
Now I need to write a macro to compare the old and new ranges and then provide the missing data as result.
I can perhaps perform the comparison part. But the problem is I don't know how to get the selected range as input in a macro.
For eg. as soon as I select a range, it should be sent as input to the macro, then the macro should wait for another selection. As soon as I select the new range, the macro should compare and find the missing lines in new range.
Regarding the selection per mouse click you could look at the link I sent in the comments of the other answer. Selection_Change is an event which gets triggered when you change the selection of a worksheet (not only mouseclick but move-by-keys as well). The target coming in is the cell which you have selected. You can pass this as a range on to a function.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
showMsg Target
End Sub
Private Function showMsg(r As Range)
MsgBox r.Address
End Function
You can just as well use another event like BeforeDoubleClick or BeforeRightClick. Check out the events of Excel and choose the one you feel fits best.
If you only want the function to be triggered for a certain range you can filter it.
If target.column <> 1 then exit function
If you don't want the event to trigger your function each time you change a selection you can choose one cell to be the switch which gets triggered by the same event.
If target.address = "$A$1" Then Call toggleSearch()
with toggleSearch being the switching function.
This is a classical diff (and a simple one at that), you shouldn't select by hand or anything. Just sort the two lists in an identical way, then run a Sub which loops over the number of rows in the source sheet comparing each row with the same row in the target sheet. The first mismatch you get is the missing line.
This example assumes both sheets are in the same workbook but you can easily adapt it
Public Sub diffThem()
Dim src as Worksheet, trg as Worksheet
Dim r as Range, i as Integer
Set src = ThisWorkbook.Sheets("Source")
Set trg = ThisWorkbook.Sheets("Destination")
Set r = src.Range("A1")
For i = 1 to ThisWorkbook.Sheets("Source").UsedRange.Rows.Count
If r.EntireRow <> trg.Range("A" & r.Row).EntireRow Then
MsgBox("The missing row is " & r.Row)
Exit Sub
End if
Set r = r.Offset(1,0)
Next i
End Sub
If EntireRow cannot be run due to different layouts or whatever then loop the columns at that point.

Referring to Dynamic Named Ranges in VBA

I'm having troubling referring to a Dynamic Name Range in VBA.
My ranges are defined as
=OFFSET(Sheet!$B$2,0,0,COUNTA(Sheet!$B:$B)-1,1)
My code should search one range for all entries in another range, the intention being that any missing entries will be added. So far I have
Sub UpdateSummary()
Dim Cell As Range
Dim rngF As Range
Set rngF = Nothing
' Step through each cell in data range
For Each Cell In Worksheets("Aspect").Range("A_Date")
' search Summary range for current cell value
Set rngF = Worksheets("Summary").Range("Sum_Date").Find(Cell.Value) // Does not work
If rngF Is Nothing Then
' Add date to Summary
End If
Set rngF = Nothing
Next Cell
End Sub
The For loop seems to work ok. However, using the .Find method is giving me an error message.
Application-defined or object-defined error
It does work if I replace the named range with a specific range ($B$2:$B$5000), so it seems to be down to how the named range is being passed.
Any ideas would be appreciated.
Thanks.
The error is almost definitely because Excel can't find a named range Sum_Date that refers to a range on a worksheet named Summary. The most common causes are
Sum_Date refers to a sheet other than Summary. Check the RefersTo property of Sum_Date and make sure nothing is misspelled.
There is not a named range Sum_Date, that is, it's misspelled in the VBA code. Check the spelling of the named range in the Name Manager.
There is an error in the RefersTo formula of Sum_Date. It sounds like you already verified that this isn't the case.
I've had the a similar if not the same problem & here's how I solved it:
I first realized that the method I used to create my named range, using the Name Manager, my named range had a scope of Workbook. This is important because, it doesn't belong to the worksheet, & therefore will not be found there.
So, Worksheets("Summary").Range("Sum_Date") would not work for me.
Since my range belonged to the workbook, the way I was able to find is to use ActiveWorkbook.Names("Sum_Date")
For me I used it to remove the formula from named range that I am using in many places. The huge advantage is that named range is updated only once instead of the formula being called for every cell location that ranged is called. Huge time delay difference!
Public last_Selection As String
Private Sub Worksheet_Change(ByVal Target As Range)
'excel data change detection
If Range(last_Selection).Column = 2 Then
'Disable events, so this only executes once
Application.EnableEvents = False
'This can be done with a complex formula in a cell,
'but this is easily understood
Range("B1").End(xlDown).Select
ActiveWorkbook.Names("last_Entry").Value = ActiveCell.Row
'Re-enable so this routine will execute on the next change
Application.EnableEvents = True
End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'constantly store the last cell to know which one was previously edited
last_Selection = Target.Address
End Sub
I know this is a very old thread, but I had the same issue today and I was looking for solution for quite a long time. So maybe this will help someone.
The named "range" defined by the =OFFSET(...) formula is actually a named FORMULA, so in VBA you have to evaluate it first to get the range. E.g.:
Set rgNamedRange = Worksheets("Summary").Evaluate("Sum_Date")
Credits to a guy named "shg" from mrexcel.com, who got me on right track. :)
I have been experimenting with this for a few days and eventually I came up with the following. It may not be the most efficient but it did work for me!
The named range of "OhDear" was set up in the normal way
Dim vItem As Variant
Set vItem = Names("OhDear")
Debug.Print vItem.Name
Worth a try don't you think!
This does not work if instead of using a variant you use something like: Dim Nm as Name: Set Nm = Names("OhDear"). Any variations using 'Nm' failed!!!