Excel VBA snippet causing Run-Time Error '438' - excel

1st time poster.
The following VBA script breaks a work macro everytime. I've tried different syntaxes to fix, but getting the same result.
The code is supposed to look through all data cells in column L, looking for the string, "ERROR". If found, copy that cell and the one to the right over to the correct column "AX" and clear the text in L and M.
The step it breaks at every time is the "Cells(i, 50).Paste" line.
Set rng = Application.Range("L4:M" & lrow)
For i = rng.Rows.Count To 4 Step -1
If Cells(i, 12).Value = "ERROR" Then
Range("L" & i & ":M" & i).Copy
Cells(i, 50).Paste
Range("L" & i & ":M" & i).ClearContents
End If
If Cells(i, 21).Value = "ERROR" Then
Rows(i).Delete
End If
Next I

Paste is not a method available to the Range object. Cells is a Range object. Ergo, "Object does not support this property or method" :)
You could try:
Cells(i, 50).PasteSpecial xlPasteAll

As #DavidZemens said, you missed the proper method name
furthermore your code seems to do unnecessary work where:
it first does something in current i row should If Cells(i, 12).Value = "ERROR" check return True
then it would delete the same i row should subsequent If Cells(i, 21).Value = "ERROR" Then return True again
Finally you're not using any PasteSpecial feature so you may want to use plain Copy one
Hence I'd refactor it as follows
Dim lrow As Long, i As Long
lrow = Cells(Rows.Count, "L").End(xlUp).Row
For i = lrow To 4 Step -1
If Cells(i, 21).value = "ERROR" Then
Rows(i).Delete
ElseIf Cells(i, 12).value = "ERROR" Then
Range("L" & i & ":M" & i).Copy Destination:=Cells(i, 50)
Range("L" & i & ":M" & i).ClearContents
End If
Next i

Related

Add the sum of the total amount from the sheet

Thanks for opening my thread. I need help from you.
So in this sheet the total amount should be sum of fuel + surge + delivery_charge should be added in Total amount column.
Ex:- 1st order = 456777 this should add 109.49+303.41+25966.51 = 26379.41
2nd order = 23213213 should add 10+11318+65 = 11393
Dim i As Long, lastrow As Long, rng As Long
lastrow = Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow
If Cells(i, "A") <> "" Then
rng = Cells(i, "A").End(xlDown).Row - 1
Cells(i, "B").Value = WorksheetFunction.Sum(Range("C" & i & ":C" & rng), Range("E" & i & ":E" & rng), Range("G" & i & ":G" & rng))
End If
Next i
I'm getting output from this logic :
But the issue is for 2nd order id. It should take only that row. But here its taking 5th and 6th row for addition.
2nd order id= 23213213 total_amt should be 11393.
So anyone could you please help me to find out an issue.
Thanks and Regards,
Ranger
The issue is in how you find rng.
rng = Cells(i, "A").End(xlDown).Row - 1
You're using xlDown to find the start of the next block of data. This works as you'd expect, except where the data changes every cell. If you click on cell A5 and press CTRL-Shift-Down, you'll see that it selects three cells as it jumps to the end of that block of data (A7). This is normal Excel behaviour.
You could re-write your code to loop through all the data until it finds the right scenario, but in this case I believe the single cell issue can just be trapped with the right If statement.
If Cells(i + 1, "A") <> "" Then rng = i
Try this:
Dim i As Long, lastrow As Long, rng As Long
lastrow = Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow
If Cells(i, "A") <> "" Then
rng = Cells(i, "A").End(xlDown).Row - 1
If Cells(i + 1, "A") <> "" Then rng = i
Cells(i, "B").Value = WorksheetFunction.Sum(Range("C" & i & ":C" & rng), Range("E" & i & ":E" & rng), Range("G" & i & ":G" & rng))
End If
Next i

Deleting Cells after Concatenation in VBA

I am trying to reformat a text file that has been imported into Excel.
I have done several minor reformatting points including adding rows, deleting page numbers, and combining headlines back into a single cell via the & function (the text file was delimited when importing).
After a concatenate, in which I took certain cells from columns A-Z and combined them in Column A, I tried to delete the now redundant information from Columns B-Z.
I tried selecting the cells and deleting, and also Range.Clear, but it does not delete the cells. I receive no errors.
This is what I have to take care of this step:
'Fix Duplicate Cells from Concatenate
For i = lastRow2 To 2 Step -1
If IsEmpty(Range(i, 1).Offset(-1, 0)) = True Then
ActiveSheet.Range(Cells(i, 2), Cells(i, 26)).Clear
End If
Next
Ultimately, I would like to check if column A contains no information one row above the row where I would like to delete information from columns B-Z.
Full code:
Sub Format()
'This will delete page numbers
Dim lRow As Long
Dim iCntr As Long
lRow = 350
For iCntr = lRow To 1 Step -1
If IsNumeric(Cells(iCntr, 1)) Then
Rows(iCntr).Delete
End If
Next
'Add Row above each row with Headings
Dim lRow2 As Long, iRow As Long
With Worksheets("Sheet1")
lRow2 = .Cells(.Rows.Count, "A").End(xlUp).Row ' last row in column A
'loop backwards (bottom to top = Step -1) through all rows
For iRow = lRow2 To 1 Step -1
'check if column A of current row (iRow) is "DIM"
If .Cells(iRow, "A").Value = "DIM" Then
.Rows(iRow).Resize(RowSize:=1).Insert xlShiftDown
'insert 1 row and move current (iRow) row down (xlShiftDown)
'means: insert 1 row ABOVE current row (iRow)
End If
Next iRow
End With
'Combine Headings back to single Cell
Dim lngLastRow As String
Dim lastRow As Long
Dim lastcolumn As Long
lastRow = ActiveSheet.UsedRange.Row - 1 + ActiveSheet.UsedRange.Rows.Count
lastcolumn = ActiveSheet.UsedRange.Column - 1 + ActiveSheet.UsedRange.Columns.Count
For i = lastRow To 1 Step -1
If Cells(i, 1).Value = "DIM" Then
Cells(i, 1).Value = Cells(i, 1).Value & " " & Cells(i, 2).Value & " " & _
Cells(i, 3).Value & " " & Cells(i, 4).Value & " " & Cells(i, 5).Value & " " & _
Cells(i, 6).Value & " " & Cells(i, 7).Value & " " & Cells(i, 8).Value & " " & _
Cells(i, 9).Value & " " & Cells(i, 10).Value & " " & Cells(i, 11).Value & " " & _
Cells(i, 12).Value & " " & Cells(i, 13).Value & " " & Cells(i, 14).Value & " " & _
Cells(i, 15).Value & " " & Cells(i, 16).Value & " " & Cells(i, 17).Value & " " & _
Cells(i, 18).Value & " " & Cells(i, 19).Value & " " & Cells(i, 20).Value & " " & _
Cells(i, 21).Value & " " & Cells(i, 22).Value & " " & Cells(i, 23).Value & " " & _
Cells(i, 24).Value & " " & Cells(i, 25).Value & " " & Cells(i, 25).Value
End If
Next
'Fix Duplicate Cells from Concatenate
For i = lastRow2 To 2 Step -1
If IsEmpty(Range(i, 1).Offset(-1, 0)) = True Then
ActiveSheet.Range(Cells(i, 2), Cells(i, 26)).Clear
End If
Next
End Sub
The reason I have a condition set for the clearing of cells after concatenate is because I do not simply want to clear all cells in range B:Z, or even the specific rows in this range. I only want to clear this range in the instances where there is a blank line above it (headers to data). The reason being: I am trying to keep the spreadsheet as generic as possible in order to use it again if the specific layout of rows changes based on the input file.
First, the variable lastRow2 doesn't seem to be declared, and as you don't get any errors, you obviously don't use Option Explicit. Please do, because that will warn you about such errors.
Secondly, I don't see that you in any way initialize lastRow2, which explains why the loop is never run. Did you run the code in the debugger to verify values of variables and progress of the execution? That is the first thing to do when you see unexpected results.
Thirdly, I don't understand why you have the condition and why you use offset If IsEmpty(Range(i, 1).Offset(-1, 0)) = True. Just clear the cells explicitly
Try this instead:
lastColumn = 26
For i = lastRow To 1 Step -1
Range(Cells(i, 2), Cells(i, lastColumn)).Clear
Next
edit:
I noticed you have the last column as 25 (as well as the previous one) in the part where you concatenate the values from the cells. The correct last column is 26.
edit2:
Based on your edit of your question and assuming you have declared and initialized lastRow2 the corrected function would look like this:
For i = lastRow2 To 2 Step -1
If IsEmpty(Range(Cells(i, 1), Cells(i, 1)).Offset(-1, 0)) = True Then
ActiveSheet.Range(Cells(i, 2), Cells(i, 4)).Clear
End If
Next

Create a checkpoint in a foreach statement

I am writing a code that put an X in a cell depending on a offset cell value, for exemple if the offset cell has a value of 3, it will put an X in the cell and decrement the offset cell value, i want to save the location of that cell and start the next for each with it.
For Each Cell In plage
If (Cell.Offset(0, 1).Value <> 0) Then
If (Cell.Value <> "X") Then
Cell.Offset(0, 1).Value = Cell.Offset(0, 1).Value - 1
Cell.Value = "X"
Checkpoint = Cell.Address
Exit For
Else
Cell.Value = ""
GoTo NextStep
End If
Exit For
Else
Cell.Value = ""
End If
NextStep:
Next Cell
The problem i am having with the current code is it start the loop all over again while i want it to keep till the end of the lines, until all offset value are equal to 0.
Try the below (there are notes on the code). If you face difficulties let me know.
Option Explicit
Sub test()
'In this example we assume that the data you want to loop appear in Column A
Dim i As Long, Lastrow As Long
Dim Checkpoint As Variant
With ThisWorkbook.Worksheets("Sheet1") '<- Change sheet name if needed
Lastrow = .Cells(.Rows.Count, "A").End(xlUp).Row '< -Fins the lastrow of the column you want to loop
For i = 2 To Lastrow ' < -Start looping from row 2 to Lastrow fo the column
If .Range("A" & i).Offset(0, 1).Value <> 0 Then '<- You are looping
If .Range("A" & i).Value <> "X" Then
.Range("A" & i).Offset(0, 1).Value = .Range("A" & i).Offset(0, 1).Value - 1
.Range("A" & i).Value = .Range("A" & i).Value & "X"
Checkpoint = .Range("A" & i).Address
Else
.Range("A" & i).Value = ""
End If
Else
.Range("A" & i).Value = ""
End If
Next i
End With
End Sub
Is plage a range?
If so, you could update it to start from the checkpoint and include all cells up to some lastCell for example.
Something like:
set plage=thisWorkbook.Worksheets("Your Worksheet").Range(checkpoint,lastCell)
That way the next For-Each should start from your checkpoint.
BTW if I understand correctly what you'e trying to do, I would suggest you replace cell.value="" with cell.clearContents

Runtime error '1004': application or object defined error

Runtime error '1004': application or object defined error
Hey I cant find out why my code isn't working. I know it's somewhere in the right hand side of the formula. I've highlighted the error for you.
Private Sub CommandButton1_Click() 'accept button
Blank:
machine = TextBox1.Value
rates = TextBox2.Value
If machine = "" Then 'if blank
MsgBox ("Please type in a machine name.")
GoTo DONE
ElseIf rates = "" Then 'if rates is blank
MsgBox ("Please type in a rate for machine.")
GoTo DONE
End If
For i = 1 To 50 'search database
If LCase(Worksheets("database").Cells.Range("B2").Offset(0, i)) = LCase(machine) Then 'if name is in database
MsgBox (machine & " is already in database. Choose another name.")
GoTo DONE
ElseIf IsEmpty(Worksheets("database").Cells.Range("B2").Offset(0, i)) Then 'if it's not
Range("B:B").Offset(0, i).Select
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Worksheets("database").Cells.Range("B2").Offset(0, i) = machine
Worksheets("database").Cells.Range("B2").Offset(0, i).HorizontalAlignment = xlLeft
Worksheets("database").Cells.Range("B2").Offset(-1, i) = rates
For j = 1 To 50
If LCase(Range("A1").Offset(j, 0)) = "total hours" Then
ActiveSheet.Range("B1").Offset(j, i).Formula = "=sum(" & Range(Cells(3, i + 2), Cells(j, i + 2)).Address(False, False) & ")"
ActiveSheet.Range("B1").Offset(1 + j, i).Formula = "=product(sum(" & ActiveSheet.Range(Cells(3, i + 2), Cells(j, i + 2)).Address(False, False) & "," & ActiveSheet.Range(Cells(1, 2 + i)) & ")"
GoTo Cancel
End If
Next j
GoTo Cancel
End If
Next i
Cancel:
DONE:
End Sub
the line that i separate from the others is the one in question.
Thanks!
Hard to know without a description of what you are trying to do. But perhaps:
"=product(sum(" & ActiveSheet.Range(Cells(3, I + 2), Cells(J, I + 2)).Address(False, False) & "," & ActiveSheet.Cells(1, 2 + I).Address & "))"
You need to analyze each part of the line by itself to see what is causing the error. Then put them together after verifying the parts.
Dim HoursRangeAddress As String
Dim RateRangeAddress As String
HoursRangeAddress = ActiveSheet.Range(Cells(3, i + 2), Cells(j, i + 2)).Address(False, False)
RateRangeAddress = ActiveSheet.Cells(1, i + 2).Address
Debug.Print HoursRangeAddress
Debug.Print RateRangeAddress
ActiveSheet.Range("B1").Offset(1 + j, i).Formula = _
"=product(sum(" & HoursRangeAddress & ")," & RateRangeAddress & ")"
You were missing a parenthesis ) after your sum. But also this caused an error: ActiveSheet.Range(Cells(1, 2 + i)) Try this instead: ActiveSheet.Cells(1, 2 + i).Address
Using R1C1 Notation: You should really learn R1C1 notation. Once you are familiar with it, your code is much easier to write and read. You can replace all of the lines of code above with this one line:
ActiveSheet.Range("B1").Offset(1 + j, i).FormulaR1C1 = "=R1C*R[-1]C"
I understand now that you are trying to multiply the rate in row one by the total hours one row above this formula.
It's so much better to use R1C1 notation in a situation like this. You can avoid entirely the need to create string addresses for the formulas. Your formula becomes very simple and easy to read.

VBA code to select a cell when specific letters appears and sort

I need some help to understand and modify some code I found in this answer:
Sub Main()
Dim cell As Range
Dim nextRow As Long
For Each cell In Range("K50:K200")
If StrComp(cell, "Late", vbTextCompare) = 0 Then
nextRow = Range("J" & Rows.Count).End(xlUp).Row + 1
Range("J" & nextRow) = Range("B" & cell.Row)
Range("K" & nextRow) = Range("C" & cell.Row)
Range("N" & nextRow) = Range("G" & cell.Row)
Range("O" & nextRow) = Range("H" & cell.Row)
End If
Next
End Sub
What I'd like is:
If late is along with some other words, say late submit, copy values in B and paste in J
if row K has progress along with say in progress, copy values in C to K
If sick is with say on sick leave, copy values in G to N
I tried so hard, but I still didn't succeed in modifying this code to suit my needs.
If late is along with some other words, say late submit
In that case, instead of StrComp, use Instr
If Instr(1, cell, "Late", vbTextCompare) > 0 Then
Similarly for the rest.
If you check Excel's help you will notice that Instr returns a Variant (Long) specifying the position of the first occurrence of one string within another.
Syntax
InStr([start, ]string1, string2[, compare])

Resources