Error on Set range statement - vba

Can someone please help with this code? It throws an error on the 6th line (Set rng = Sheet3.Range(Cells(1,i),Cells(1,j)).Select) but i don't know how to fix it.
Public Sub CommandButton1_Click()
Dim i As Integer
i = 3
Dim j As Integer
j = 5
Set Rng = Sheet3.Range(Cells(1, i), Cells(1, j)).Select
lAnswer = Application.WorksheetFunction.Sum(Rng)
Sheet1.Cells(5, 13).Value = lAnswer
End Sub

You have received an answer to the syntax issue but I would also caution you about orphaned cell references in the use of the two Range.Cells properties used to define the scope of the Range object. Specifically, their Range .Parent property is arbitrary.
Public Sub CommandButton1_Click()
Dim i As Long
Dim j As Long
Dim Rng As Range
Dim lAnswer As Double
i = 3
j = 5
with Sheet3
Set Rng = .Range(.Cells(1, i), .Cells(1, j))
end with
lAnswer = Application.WorksheetFunction.Sum(Rng)
Sheet1.Cells(5, 13).Value = lAnswer
End Sub
That one line could also be written as,
Set Rng = Sheet3.Range(Sheet3.Cells(1, i), Sheet3.Cells(1, j))
... but the With...End With statement cleans it up tidily. Without specifying the parent of .Cells, you run the risk of trying to define a range on Sheet3 that includes the cells from another worksheet. I realize that this is a command button and arbitrary cell range parentage should implicitly be the worksheet containing the button clicked but you are defining Sheet3 for the .Range so good coding practise dictates that you complete the exercise by explicitly defining Sheet3 as the parent of the nested .Cells.

Just remove the 'select' part of that line.
Public Sub CommandButton1_Click()
Dim i As Integer
Dim j As Integer
Dim Rng As Range
Dim lAnswer As Long
i = 3
j = 5
Set Rng = Sheet3.Range(Cells(1, i), Cells(1, j)) 'remove '.select'
lAnswer = Application.WorksheetFunction.Sum(Rng)
Sheet1.Cells(5, 13).Value = lAnswer
End Sub

Related

Get CurrentRegion only in vertical direction

I would like to write a UDF (user defined function, aka. macro) that will be used in each of the green cells. In this function/macro in want to get the length of the longest string in the framed cells next to my current group of green cells. In order to do this in the macro I need to determine a range that represents all of the framed cells next to the current cell. (This calculation should result the same range object for each cell in one green group but a different one from group to group.) How would you get this Range?
My first try was this:
Range(Application.Caller.Offset(0, -1).End(xlUp),_
Application.Caller.Offset(0, -1).End(xlDown))
But this
doesn't work
would give false range if the caller cell is the uppermost or lowermost cell of a group.
I would need something like ActiveCell.Offset(0, -1).CurrentRegion, but in the vertical direction only.
Try this:
Function findlongest()
Dim fullcolumn() As Variant
Dim lastrow As Long
Dim i As Long, j As Long, k As Long
Dim tmax As Long
tmax = 0
With Application.Caller
lastrow = .Parent.Cells(.Parent.Rows.Count, .Column - 1).End(xlUp).Row
fullcolumn = .Parent.Range(.Parent.Cells(1, .Column - 1), .Parent.Cells(lastrow, .Column - 1)).Value
For j = .Row To 1 Step -1
If fullcolumn(j, 1) = "" Then
j = j + 1
Exit For
ElseIf j = 1 Then
Exit For
End If
Next j
For i = .Row To UBound(fullcolumn, 1)
If fullcolumn(i, 1) = "" Then
i = i - 1
Exit For
ElseIf i = UBound(fullcolumn, 1) Then
Exit For
End If
Next i
'to get the range
Dim rng As Range
Set rng = .Parent.Range(.Parent.Cells(j, .Column - 1), Parent.Cells(i, .Column - 1))
'then do what you want with rng
'but since you already have the values in an array use that instead.
'It is quciker to iterate and array than the range.
For k = j To i
If Len(fullcolumn(k, 1)) > tmax Then tmax = Len(fullcolumn(k, 1))
Next k
findlongest = tmax
End With
End Function
Are you after something like the code below:
Option Explicit
Sub GetLeftRange()
Dim myRng As Range
Set myRng = ActiveCell.Offset(, -1).CurrentRegion
Debug.Print myRng.Address
End Sub
Note: ActiveCell is one of the cells you marked as green.
This is an example of setting each range using Area.
Sub test()
Dim Ws As Worksheet
Dim rngDB As Range
Dim rngA As Range, rng As Range
Set Ws = ActiveSheet
With Ws
Set rngDB = .Range("a1", .Range("a" & Rows.Count).End(xlUp))
Set rngA = rngDB.SpecialCells(xlCellTypeConstants, xlTextValues)
For Each rng In rngA.Areas
rng.Offset(, 1).Select '<~~ select is not required but is intended to be visualized
Next rng
End With
End Sub

Can't delete rows containing certain keyword within text

I have written a macro to remove rows containing certain text in it. If either of the keyword contains any text, the macro will delete the row. However, the macro doesn't work at all. Perhaps, i did something wrong in it. Hope somebody will help me rectify this. Thanks in advance.
Here is what I'm trying with:
Sub customized_row_removal()
Dim i As Long
i = 2
Do Until Cells(i, 1).Value = ""
If Cells(i, 1).Value = "mth" Or "rtd" Or "npt" Then
Cells(i, 1).Select
Selection.EntireRow.Delete
End If
i = i + 1
Loop
End Sub
The keyword within the text I was searching in to delete:
AIRLINE DRIVE OWNER mth
A rtd REPAIRS INC
AANA MICHAEL B ET AL
ABASS OLADOKUN
ABBOTT npt P
AIRLINE AANA MTH
ABASS REPAIRS NPT
Try like this.
What about Using Lcase.
Sub customized_row_removal()
Dim rngDB As Range, rngU As Range, rng As Range
Dim Ws As Worksheet
Set Ws = Sheets(1)
With Ws
Set rngDB = .Range("a2", .Range("a" & Rows.Count))
End With
For Each rng In rngDB
If InStr(LCase(rng), "mth") Or InStr(LCase(rng), "rtd") Or InStr(LCase(rng), "npt") Then
If rngU Is Nothing Then
Set rngU = rng
Else
Set rngU = Union(rngU, rng)
End If
End If
Next rng
If rngU Is Nothing Then
Else
rngU.EntireRow.Delete
End If
End Sub
VBA syntax of your Or is wrong,
If Cells(i, 1).Value = "mth" Or "rtd" Or "npt" Then
Should be:
If Cells(i, 1).Value = "mth" Or Cells(i, 1).Value = "rtd" Or Cells(i, 1).Value = "npt" Then
However, you need to use a string function, like Instr or Like to see if a certain string is found within a longer string.
Code
Option Explicit
Sub customized_row_removal()
Dim WordsArr As Variant
Dim WordsEl As Variant
Dim i As Long, LastRow As Long
Dim Sht As Worksheet
WordsArr = Array("mth", "rtd", "npt")
Set Sht = Worksheets("Sheet1")
With Sht
' get last row in column "A"
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
For i = LastRow To 2 Step -1
For Each WordsEl In WordsArr
If LCase(.Cells(i, 1).Value) Like "*" & WordsEl & "*" Then
.Rows(i).Delete
End If
Next WordsEl
Next i
End With
End Sub
I try to make my code sample as I can if you have any question please ask
Private Sub remove_word_raw()
'PURPOSE: Clear out all cells that contain a specific word/phrase
Dim Rng As Range
Dim cell As Range
Dim ContainWord As String
'What range do you want to search?
Set Rng = Range("A2:A25")
'sub for the word
shorttext1 = "mth"
shorttext2 = "rtd"
shorttext3 = "npt"
'What phrase do you want to test for?
ContainWord1 = shorttext1
ContainWord2 = shorttext2
ContainWord3 = shorttext3
'Loop through each cell in range and test cell contents
For Each cell In Rng.Cells
If cell.Value2 = ContainWord1 Then cell.EntireRow.Delete
Next
For Each cell In Rng.Cells
If cell.Value2 = ContainWord2 Then cell.EntireRow.Delete
Next
For Each cell In Rng.Cells
If cell.Value2 = ContainWord3 Then cell.EntireRow.Delete
Next cell
End Sub

Excel VBA Two functions on one array

I need to delete spaces at the beginning, end of string and make string Proper Case.
I have found two scripts:
Sub Function01()
Dim arrData() As Variant
Dim arrReturnData() As Variant
Dim rng As Excel.Range
Dim lRows As Long
Dim lCols As Long
Dim i As Long, j As Long
Range("R1", Range("R1").End(xlDown)).Select
lRows = Selection.Rows.Count
lCols = Selection.Columns.Count
ReDim arrData(1 To lRows, 1 To lCols)
ReDim arrReturnData(1 To lRows, 1 To lCols)
Set rng = Selection
arrData = rng.Value
For j = 1 To lCols
For i = 1 To lRows
arrReturnData(i, j) = Trim(arrData(i, j))
///ADDING HERE(read below)
Next i
Next j
rng.Value = arrReturnData
Set rng = Nothing
End Sub
which is deleting spaces on string and another script:
Sub ChangeCase()
Dim Rng As Range
On Error Resume Next
Err.Clear
Application.EnableEvents = False
For Each Rng In Selection.SpecialCells(xlCellTypeConstants, _
xlTextValues).Cells
If Err.Number = 0 Then
Rng.Value = StrConv(Rng.Text, vbProperCase)
End If
Next Rng
Application.EnableEvents = True
End Sub
Which is making Proper Case of string. Those two scripts are working on ranges to select all not null cells in R column. I need to make function second script in the first one.
Adding this code in first script at (///ADDING HERE) point:
arrReturnData(i, j) = StrConv(arrData(i, j), vbProperCase)
Making my output in Proper Case but with spaces.
Could you guys suggest how to make two script functions in a stroke?
Thank you!
This will do the whole without loops:
Sub Function01()
Dim rng As Range
Set rng = Selection
rng.Value = rng.Parent.Evaluate("INDEX(PROPER(TRIM(" & rng.Address & ")),)")
End Sub
Before:
After:

Handle visible cells in vba

I have a Worksheet named 'Abschluss'. In this worksheet I use filter to get the data-range I want to handle with my vba script. So i only want to handle the visible rows.
My vba Script looks like
For Each i In Worksheets("Abschluss").SpecialCells(xlCellTypeVisible).Rows
If (WorksheetFunction.CountIf(Range("B2:B" & i), Cells(i, 2)) = 1) Then _
Umsetzung_Kapitel_1.AddItem Cells(i, 2)
Next
This doesn't work, I get runtime-error 438. Do you know where the problem is?
I assume that Worksheets("Abschluss").SpecialCells(xlCellTypeVisible).Rows returns the wrong data-type, but I couldn't fix it.
It looks like you are trying to populate a combobox or a listbox with unique items, possibly in a UserForm?
Try this
Private Sub UserForm_Initialize()
Dim cUnique As Collection
Dim Rng As Range
Dim Cell As Range
Dim sh As Worksheet
Dim vNum As Variant
Set sh = ThisWorkbook.Sheets("Abschluss")
Rws = sh.Cells(Rows.Count, "B").End(xlUp).Row
Set Rng = sh.Range(sh.Cells(2, 2), sh.Cells(Rws, 2)).SpecialCells(xlCellTypeVisible)
Set cUnique = New Collection
On Error Resume Next
For Each Cell In Rng.Cells
cUnique.Add Cell.Value, CStr(Cell.Value)
Next Cell
On Error GoTo 0
For Each vNum In cUnique
ComboBox1.AddItem vNum
Next vNum
End Sub
Change to
Dim i As Long
Dim colCount As Long: colCount = Worksheets("Abschluss").SpecialCells(xlCellTypeVisible).Rows.Count
For i = 1 to colCount
....

Run-time error 1004 Application-defined or object defined error

I have looked through the other posts about this and have tried adapted the strategies that were recommend by using Set ActiveWorkbook and Set Active Worksheet and I still get the same error. I hope another set of eyes can help out as I am still very new to VBA and I am not all that comfortable with it yet.
Basically the idea is to copy the cells from column f to column j as values as long as the cells of F do not match the cells of J. I get the row count of column E and use that as my count in the for loop.
Code is here:
Private Sub CalculateRewards_Click()
CopyPaste
End Sub
Sub CopyPaste()
Dim n As Integer
Dim i As Integer
n = Sheets("Calculate").Range("E:E").Cells.SpecialCells(xlCellTypeConstants).Count
i = n
For Counter = 1 To n
Set curCell = Sheets("Calculate").Range("F2:F" &i)
If "$F" &i <> "$J" &i Then
Sheets("Calculate").Range("$F:$F" &i).Copy
Sheets("Calculate").Range("$J:$J" &i).PasteSpecial (xlPasteValues)
Application.CutCopyMode = False
End If
i = i + 1
Next Counter
End Sub
Thanks for the help
Also Edit:
Link to Excel Sheet that has a before page, after first transaction sheet ,and a after second transaction sheet: https://www.dropbox.com/s/n2mn0zyrtoscjin/Rewards.xlsm
CHange this:
Set curCell = Sheets("Calculate").Range("F2:F" &i)
If "$F" &i <> "$J" &i Then
Sheets("Calculate").Range("$F:$F" &i).Copy
Sheets("Calculate").Range("$J:$J" &i).PasteSpecial (xlPasteValues)
Application.CutCopyMode = False
End If
To this:
Set curCell = Sheets("Calculate").Range("F2:F" & i)
If curCell <> Sheets("Calculate").Range("$J" & i) Then
Sheets("Calculate").Range("$J:$J" &i).Value = curCell.Value
End If
May need to do some more teaking as I notice you're working with SpecialCells which essentially filters the range, so iterating For i = 1 to n... probably does not work. Maybe something like:
Dim rngCalc as Range
Set rngCalc = Sheets("Calculate").Range("E:E").Cells.SpecialCells(xlCellTypeConstants)
For each curCell in rngCalc.Cells
If curCell <> curCell.Offset(0, 4) Then
curCell.Offset(0, 4).Value = curCell.Value
End If
Next
EDIT: this sub will calculate the points for the last transaction (identified as the furthest-right column containing transactions) and write them down in column C.
Option Explicit
Sub UpdateCurrentPurchase()
Dim CalcSheet As Worksheet
Dim LastTransRange As Range, TargetRange As Range
Dim LastTransCol As Long, LastTransRow As Long
Dim PurchaseArray() As Variant
Dim Points As Long, Index As Long
'set references up-front
Set CalcSheet = ThisWorkbook.Worksheets("Calculate")
With CalcSheet
LastTransCol = .Cells(2, .Columns.Count).End(xlToLeft).Column '<~ find the last column
LastTransRow = .Cells(.Rows.Count, LastTransCol).End(xlUp).Row
Set LastTransRange = .Range(.Cells(2, LastTransCol), .Cells(LastTransRow, LastTransCol))
Set TargetRange = .Range(.Cells(2, 6), .Cells(LastTransRow, 6)) '<~ column F is the Current Purchase Col
LastTransRange.Copy Destination:=TargetRange '<~ copy last transactions to Current Purchase Col
End With
'pull purchases into a variant array
PurchaseArray = TargetRange
'calculate points
For Index = 1 To LastTransRow
Points = Int(PurchaseArray(Index, 1) / 10) '<~ calculate points
CalcSheet.Cells(Index + 1, 3) = Points '<~ write out the points amount in col C
Next Index
End Sub
ORIGINAL RESPONSE: I think the below will get you where you're going. That being said, it seems like simply overwriting column J with column F (as values) might be the fastest way to an acceptable answer, so if that's the case we can re-work this code to be much quicker using Range objects.
Option Explicit
Private Sub CalculateRewards_Click()
CopyPaste
End Sub
Sub CopyPaste()
Dim LastRow As Long, Counter As Long
Dim cSheet As Worksheet '<~ add a worksheet reference to save some typing
'set references up front
Set cSheet = ThisWorkbook.Worksheets("Calculate")
With cSheet
LastRow = .Range("E" & .Rows.Count).End(xlUp).Row '<~ set loop boundary
'loop that compares the value in column 6 (F) to the value in
'column 10 (J) and writes the value from F to J if they are not equal
For Counter = 1 To LastRow
If .Cells(Counter, 6).Value <> .Cells(Counter, 10).Value Then
.Cells(Counter, 10) = .Cells(Counter, 6)
End If
Next Counter
End With
End Sub