So, I have set a Range as a variable
Set Range_Count = Range("A2", Range("A2").End(xlDown))
And now I'm trying to call it in a WorksheetFunction using VBA without needing to select the worksheet
'This is what I don't want to do anymore
Sheets(1).Select
Count_Product = Application.WorksheetFunction.CountIf(Range_Count, "<>")
'This is what I'm wondering if it's possible to be done
Count_Product = Application.WokrsheetFunction.CountIf(Sheets(2).Range_Count, "<>")
But It doesn't seem to work. Is there a way to do this?
This is how it works:
Set Range_Count = Sheets(2).Range("A2", Range("A2").End(xlDown)) 'full qualify the range with it's sheet
Count_Product = Application.WorksheetFunction.CountIf(Range_Count, "<>") 'then use the range
So, I just solved it by putting the sheets before Application like this
Dim Range_Count As Range
Set Range_Count = Range("A2", Range("A2").End(xlDown))
Sheets(2).Application.WorksheetFunction.CountIf(Range_Count, "<>")
Easier than I thought
Related
My problem is relatively simple: I'm attempting to create a named range by taking the Active Sheet's Used Range but excluding Column A.
Essentially I'm attempting to figure out how to do the opposite of a Union.
How would I go about this?
Thank you.
I haven't tried any solutions as none of the solutions I've found on Google or here on StackExchange are applicable to my current situation. All of them are highly specific, and I just need a general answer on how to remove cells from a defined range.
How about this:
Sub RangeMinusFirstColumn()
Dim rng As Range
Dim sh As Worksheet
Set sh = ActiveSheet
Set rng = sh.Range("A1").CurrentRegion
Set rng = rng.Offset(, 1)
Set rng = rng.Resize(, rng.Columns.Count - 1)
End Sub
I hope someone can help me with this as it's driving me up the wall!
There are 5 non-contiguous cells in a worksheet that I want to copy to the next empty row on another worksheet whilst retaining the number formatting (which varies). I have this so far but am struggling working out how to retain formatting. Can anyone please help? Thanks I anticipation.
`With wsCalc
For bRun = 1 To 4
bData(bRun) = Application.Choose(bRun, .Range("g2"), .Range("b2"), .Range("R2"), .Range("Q14"))
Next bRun
End With
wSResults.Cells(Rows.Count, "a").End(xlUp).Offset(1).Resize(, 4).Value = bData
`
Here's a possible solution, using your hard-coded cell addresses. You will have to set wsCalc and wsResults to their proper worksheets. Slightly more elegant would be to define a "non-contiguous" range on your wsCalc sheet (select the 1st cell, keep Ctrl pressed and select the next one etc, then type a name in the drop-down box just to the left of the formula bar).
Option Explicit
Sub CopyWithFormat()
Dim wsCalc As Worksheet
Set wsCalc = ActiveSheet 'Or whatever your calc sheet is
Dim rngSource As Range
Set rngSource = wsCalc.[G2,B2,R2,Q14]
Dim wsResults As Worksheet
Set wsResults = ActiveSheet 'Or whatever your result sheet is
Dim clDest As Range
Set clDest = wsResults.Cells(Rows.Count, "a").End(xlUp).Offset(1)
Dim cl As Range
For Each cl In rngSource.Cells
clDest.Value = cl.Value
clDest.NumberFormat = cl.NumberFormat
Set clDest = clDest.Offset(1)
Next cl
End Sub
Instead of using .Value, try .Text. It retains formatting. See below.
Gary's Student is right, text is read only, it should be used for the input not the output.
bData(bRun) = Application.Choose(bRun, .Range("g2").Text, .Range("b2").Text, .Range("R2").Text, .Range("Q14").Text)
I also agree with other answer the entire code could be set up more straight forward.
So I am trying to use the autofill method in vba right now over a range that is set to a variable. I know that the range of cells you are autofilling from must be included in the destination. So, I do just that. However, and much to my surprise, all the cells in the range are being set to nothing.
Here is the code:
Dim table2Range As Range
Dim table2Range2 As Range
Dim table2Range3 As Range
Dim tableholder As Range
Set table2Range2 = Range("Y54").End(xlToRight).Offset(0, 1)
Set table2Range3 = Range("Y77").End(xlToRight).Offset(0, 1)
Set table2Range = Range(table2Range2, table2Range3)
Set tableholder = Range("y54", table2Range3)
tableholder.Select
table2Range.AutoFill Destination:=Selection 'This is setting all my cells to nothing for some reason
Here is the before & after screenshots:Before, After
Any help is hugely appreciated!
Your AutoFill line of code should be:
SourceRange.AutoFill Destination:FillRange
It seems like your "table2Range " is the source, which overlap with your Fill Range. I.e:
.End(xlToRight).Offset(0, 1) will set range from Y54 to the rightmost cell of the same row.
You can edit the source range with hardcode first (i.e. Range("Y54:Z77") and see if that works for you, then work from there
For example (try on a new workbook):
Sub example()
Set SourceRange = Worksheets("Sheet1").Range("A1:B1")
Set fillRange = Worksheets("Sheet1").Range("A1:G1")
SourceRange.AutoFill Destination:=fillRange
End Sub
Enter "1" in cell(A1) and "2" in Cell(B1) and run the code.
1) My objective is the following one:
To replace the content of a cell with a conditional statement that is either "Monitorato" or "Non Monitorato". The Condition determining the type of statement is the output of a Vlookup function. IF vlookup finds a value I would have "Monitorato", while if this does not happen I would have "Non Monitorato".
2) By using traditional excel functions, the thing is solved In this way:
=IF(ISNA(VLOOKUP(cell to look for, range, column, false)),"Non Monitorato","Monitorato")
I then copy and paste this formula to all the cells below the one I wrote the initial formula
3) However I would like to implement this thing using VBA.
Moreover, there is an additional problem. The data are actually filtered, so I need to use the Vlookup function only on the filtered data. The Vlookup function should look for the first visible cell in the dataset.
4) The horrible code that I wrote is the following one:
Sub MyFunction()
Dim i As Long
Dim LastRow As Long
Dim FirstRow As Long
Dim Header As Range
Set Header = Range("d1")
FirstRow = Range(Header.Offset(1, 0), Header.End(xlDown)).SpecialCells(xlCellTypeVisible).Cells(1).Count
LastRow = ActiveSheet.UsedRange.Rows.SpecialCells(xlCellTypeVisible).Count
For i = FirstRow To LastRow
Sheets(1).Cells(FirstRow, 5) = Application.WorksheetFunction.VLookup(Sheets(1).Cells(i, 3), Sheets(1).Range("C2:D100"), 2)
Next i
End Sub
The error I am getting is
Unable to get the vlookup property of the worksheet function class
I would like to solve it, but I also know there must be an easier solution to the problem...
Thank you all!
There's actually several issues with the current code and it will not accomplish what you are after. See if this code works for you:
Sub Monitorato()
Dim ws1 as Worksheet
Set ws1 = Sheets(1)
Dim rLookup As Range, rCell as Range
With ws1
Set rLookup = .Range(.Range("D1"),.Range("D1").End(xlDown)).SpecialCells(xlCellTypeVisible)
For each rCell in rLookup
If Not .Range("C2:D100").Find(rCell.Offset(,-1).Value2) Is Nothing Then
rCell.Offset(,1).Value = "Monitorato"
Else
rCell.Offset(,1).Value = "Non-Monitorato"
End If
Next
End With
End Sub`
I was helping a friend work out a problem with VBA in Excel 2007 today, and we ran into an issue I think I'd encountered and worked around in the past. It's an issue with changing the range to which a name refers.
On my friend's main worksheet, in B7, she has data validation from a List where the Source is a named range, CAT_LOOKUP. She wanted to run a sub that would filter a table on another worksheet to show only rows that correspond to the value in B7 and then use those rows as the source for validation in another cell on that worksheet.
Here's the relevant part of the VBA we were using:
Dim strCAT As String
Dim strACT As String
Dim sh As Worksheet
Dim rng As Range
Dim rngDest As Range
If Cells(7, 2) <> "" Then
strCAT = Cells(7, 2).Value
Sheets("CAT LOOKUP").Range("$A2:$C393").AutoFilter Field:=1, _
Criteria1:=strCAT
Set sh = Sheets("CAT LOOKUP")
Set rng = sh.Range("B34:B56")
rng.ClearContents
Set rng = sh.Range(sh.Range("B1"), sh.Range("B1").End(xlDown))
rng.Copy
Set rngDest = sh.Range("B34")
rngDest.PasteSpecial
ActiveWorkbook.Names("CAT_LOOKUP").RefersToRange = _
sh.Range(sh.Range("B35"), sh.Range("B35").End(xlDown))
Else
Set sh = Sheets("CAT LOOKUP")
Set rng = sh.Range("B34:B56")
rng.ClearContents
Sheets("Ad Hoc Request").Select
End If
CAT_LOOKUP is already defined. When this code is run, the CAT_LOOKUP range is cleared, and the definition of the range is unchanged.
I found in my notes from an old project that I'd used RefersToR1C1 instead of RefersToRange, so I changed that line to this:
ActiveWorkbook.Names("CAT_LOOKUP").RefersToR1C1 = _
"='CAT LOOKUP'!R35C2:R" & sh.Range("B35").End(xlDown).Row & "C2"
and the code worked as desired, resetting the named range so that the corresponding data validation works properly.
Is this simply a bug in the implementation of RefersToRange, or is there a problem with the way we were using it?
RefersToRange is read-only, at least in XL 2003 and probably in 2007.