Remove Cells from a Defined Range - excel

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

Related

If and Loop function

Master Dataset- Sheet1
Sub Dataset- Sheet2
Similar to the question on If and Loop function to extract data, I have two worksheets. I am trying to use VBA to input Column M for me- the x's. For example, to the left of apple should be 123, as it is its code, and orange 456 etc., according to the Master Dataset. Because it is a similar problem as the one on the aforementioned site, I tweaked the code a little, but it would not work. It is as follows:
Option Compare Text
Sub DataExtraction()
Dim SrchRng As Range, cel As Range, rngDest as Range
Dim ws1 As Worksheet, ws2 As Worksheet
Set ws1 = Worksheets("Sheet1")
Set ws2 = Worksheets("Sheet2")
'restrict the search range
Set SrchRng = Application.Intersect(ws1.Range("F;F"), ws1.UsedRange)
Set rngDest = ws2.cells(rows.count, 1).end(xlUp).Offset(1, 0) 'start copy here
For Each cel In SrchRng.Cells
If cel.value=rngDest.value Then
rngDest.offset(0, -1).value = cel.offset(0, -1).value
Set rngDest = rngDest.offset(1, 0) '<< next row down
End If
Next cel
End Sub
In short, I am trying to tell VBA that if the Fruit of interest matches, then input the Code found in Column D of Sheet1 into Column M of Sheet 2 accordingly, then move to the next row and repeat the exercise. Any help would be greatly appreciated.
P.S. A very special thanks to Tim Williams for solving my problem previously, and hitherto helping me to set up this model that I used to develop.
There is an easy solution without using VBA. You could do that with formulas too with a combination of MATCH() and INDEX(). This should even be faster.
Just use
=INDEX(Sheet1!D:D,MATCH(N:N,Sheet1!F:F,0))
If you need to automate it, I would write this formula into column M (and if necessary convert the formulas into values):
Option Explicit
Public Sub FillInCodes()
Dim wsSub As Worksheet
Set wsSub = ThisWorkbook.Worksheets("Sheet2")
Dim LastRow As Long
LastRow = wsSub.Cells(wsSub.Rows.Count, "A").End(xlUp).Row
wsSub.Range("M2:M" & LastRow).Formula = "=INDEX(Sheet1!D:D,MATCH(N:N,Sheet1!F:F,0))"
'and if you need to convert the formulas into values
wsSub.Range("M2:M" & LastRow).Value = wsSub.Range("M2:M" & LastRow).Value
End Sub

Calling a Range (as a variable) in a different Worksheet

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

Removing Blanks from Dynamic Range

I understand how to use the offset function for a dynamic range, but what if that dynamic range is within a specific number of additional columns? For example, say I have a worksheet with columns A:N, and the named range refers to D2:E2. If I add two more columns, that range should expand to D2:G2, but not include columns F and onward.
I'm currently using the offset function with the counta function to do this, but there are a number of natural blank cells within this range (because of merged cells). Is there a way for me to remove these blanks for use in the combobox's dropdown?
Currently I've defined the name as:
=OFFSET('Sheet 1'!$D$2,0,0,1,COUNTA('Sheet 1'!$D2:$ZZ2))
Which returns all of the values I'm looking for, but several blanks as well that I don't want in the dropdown.
I'm currently using the following code during the userform's initialization, but this doesn't seem to be working either:
Dim Rng As Range
Dim i As Long
Me.ComboBox1.RowSource = ""
Set Rng = Range("Combo")
For i = 1 To Rng.Rows.Count
If Rng(i) <> "" Then
Me.ComboBox1.AddItem Rng(i)
End If
Next i
I've also tried
Dim aCell As Range, ws1 As Worksheet, lastColumn As Long, stopColumn As Long
Set ws1 = Worksheets("sheet 1")
With ws1
lastColumn = .Cells(1, .Columns.Count).End(xlToLeft).Column
stopColumn = lastColumn - 12
Me.ComboBox1.RowSource = ""
With ws1
For Each aCell In .Range("D2", .Cells(2, stopColumn))
If aCell.Value <> "" Then
Me.ComboBox1.AddItem aCell.Value
End If
Next
End With
Neither attempt has worked though, the combobox dropdown is empty.
The second part of the code above actually was functional, I was just using the wrong procedure name. I was using UserForm2, and had renamed the initialize procedure Private Sub UserForm2_Initialize() when it should have instead been `Private Sub UserForm_Initialize()

How to use a For loop with Vlookup in Excel using Variables to identify cells

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`

For Each In: Is it possible to run through a single-column range and paste multiple columns, starting with that first FOR cell?

I've been having trouble trying to optimize a certain part of my code. I am performing a Monte Carlo simulation and I want to copy the values of a range a repeated number of times. To do this, I've used a For Each In structure. Below is a minimal example.
sub example()
Dim live As Excel.Range 'the range to be copied in each For Each In
Dim acell as Excel.Range 'For range
Set live = Range("C5:P5")
For Each acell in Range("B9:B90")
acell.value=live.value
Next acell
End Sub
The problem is that live spans multiple columns, while acell is just one cell; what ends up happening is just the first column is copied, the rest are blank. I have also used For Each acell in XYZ.rows where XYZ is a previously defined range of multiple columns and rows. However, this is considerably slower.
Is it possible to run through a single-column range and paste multiple columns, starting with that first cell?
Is this what you are looking for?
Sub example()
Dim live As Excel.Range 'the range to be copied in each For Each In
Dim acell As Excel.Range 'For range
Set live = Range("C5:P5")
live.Copy
Range("B9").PasteSpecial xlPasteValues, , , True
End Sub
You're almost there; you're just missing a tiny change in your code. You have to Resize the target range. Instead of
bcell.value=live.value ' bcell (presumably a typo) is only 1 column wide
use
acell.Resize(1, live.Columns.Count).Value = live.Value
It might be best to read C5:P5 in as an array:
Sub CopyLoop()
Dim copyRng(), targetRng As Range, cl As Range
copyRng = Range("C5:P5") 'Read in as array
Set targetRng = Range("B9:B90")
For Each cl In targetRng
Range("B" & cl.Row & ":O" & cl.Row) = copyRng
Next cl
End Sub

Resources