Excel VBA Loop That Not Stops Based On Activecell Value - vba

I have a loop that needs to stop when activecell value is "BBSE", but it passes the cell and continues the loop. someone can help me with that?
I cut rows from table in one workbbok and paste it to another. before the list in column F I have many blank cells, and because of that I am usind xldown.
Here is the relevant code:
'Illuminators Worksheet
OP_wb.Activate
Range("F2").End(xlDown).Select
Do Until ActiveCell.Value = "BBSE"
OP_wb.Activate
Worksheets("Optic Main").Activate
Range("F2").End(xlDown).Select
Selection.EntireRow.Cut
Demand_WB.Activate
Worksheets("Illuminators").Activate
Range("A" & Rows.Count).End(xlUp).Offset(1).Select
ActiveSheet.Paste
Loop
Here is where I want to stop the loop in the red circle:
this is why I am using END.xlDown

If I understand what you are trying to achieve correctly, I believe the following will achieve it:
Dim startRow As Long
Dim endRow As Long
With OP_wb.Worksheets("Optic Main")
startRow = .Range("F2").End(xlDown).Row
endRow = .Columns("F").Find(What:="BBSE", LookIn:=xlValues, LookAt:=xlWhole).Row
.Rows(startRow & ":" & endRow).Cut
End With
With Demand_WB.Worksheets("Illuminators")
.Range("A" & .Rows.Count).End(xlUp).Offset(1).Insert Shift:=xlDown
End With

May be try like this...
'Mentioning Starting Row Here
x = 2
Do
'x refers to Row and F refer to column name
With Cells(x, "F")
'Exiting Do Loop once it finds the matching value using If statement
If .Value = "BBSE" Then Exit Do
OP_wb.Activate
Worksheets("Optic Main").Activate
.EntireRow.Cut
Demand_WB.Activate
Worksheets("Illuminators").Activate
Range("A" & Rows.Count).End(xlUp).Offset(1).Select
ActiveSheet.Paste
End With
'Incrementing row number here to move on to next row
x = x + 1
Loop

Related

macro: copy paste cell if condition met

There’s one step that’s stuck, to update the stock number (column "D") in the database_ gudang (stock in the database_ gudang is added to the amount of receipt (column "K") from form_penerimaan)
The update is based on the name of the item (nama barang), so if the name of the item (column "C") in the form_penerimaan is the same as the name of the item (column "B") in the database_ gudang, the stock in database_ gudang will be updated.
but there’s a problem, which is updated only in rows 2,9,10 (yellow cell). A row of 3,4,5 should also be updated.
Thank you very much for your help.
Regards.
Sub Module1()
s = 10
OT1 = Sheets("Database_Gudang").Cells(Rows.Count, "D").End(xlUp).Row
For j = 2 To OT1
NB1 = Sheets("Database_Gudang").Cells(j, "B").Value
Sheets("Form_Penerimaan").Activate
If Cells(s, "C").Value = NB1 And Cells(s, "C").Value <> "" Then
Sheets("Form_Penerimaan").Cells(s, "Q").Copy
Sheets("Database_Gudang").Activate
Sheets("Database_Gudang").Cells(j, "G").Select
Selection.PasteSpecial Paste:=xlPasteValues
s = s + 1
End If
Next j
End Sub
Hi and Welcome to stackoverflow :)
Avoid the use of .Select and .Activate. Directly work with variables and objects. You may want to see How to avoid using Select in Excel VBA
You are facing that issue because you are not looping through the cells of the 2nd sheet.
Is this what you are trying? (UNTESTED)
I have commented the code so you may not have a problem in understanding it. If you do then share the exact error message and we will take it from there.
Sub Sample()
Dim wsThis As Worksheet, wsThat As Worksheet
Dim i As Long, j As Long
Dim wsThisLRow As Long, wsThatLRow As Long
'~~> Set your worksheets
Set wsThis = ThisWorkbook.Sheets("Database_Gudang")
Set wsThat = ThisWorkbook.Sheets("Form_Penerimaan")
'~~> Find relevant last row in both sheets
wsThisLRow = wsThis.Range("D" & wsThis.Rows.Count).End(xlUp).Row
wsThatLRow = wsThat.Range("C" & wsThat.Rows.Count).End(xlUp).Row
With wsThis
'~~> Loop through cell in Database_Gudang
For i = 2 To wsThisLRow
'~~> Loop through cell in Form_Penerimaan
For j = 10 To wsThatLRow
'~~> Compare values and get values across if applicable
If .Range("B" & i).Value = wsThat.Range("C" & j).Value Then
.Range("G" & i).Value = wsThat.Range("Q" & j).Value
Exit For
End If
Next j
Next i
End With
End Sub

Filter loop Excel Macro

I am trying to use the AutoFilter and getting the criteria using a values from a different sheet, however its only getting the count value of the last record in the loop.
For iLoop = 1 To 10
Selection.AutoFilter Field:=8, Criteria1:=Worksheets("Sheet3").Cells(iLoop, 1).Value
Dim LR As Long
LR = Range("A" & Rows.Count).End(xlUp).Row
Range("A2:AD" & LR).SpecialCells(xlCellTypeVisible).Select
ActiveSheet.Range("$A$1:$AD$146").AutoFilter Field:=5, Criteria1:=RGB(255, _
0, 0), Operator:=xlFilterCellColor
cCnt = ActiveSheet.AutoFilter.Range.Columns(5).SpecialCells(xlCellTypeVisible) _
.Cells.Count - 1
ActiveSheet.ShowAllData
Worksheets("Sheet3").Range("B2:B11").Value = cCnt
Next iLoop
It looks like your problem is that this:
Worksheets("Sheet3").Range("B2:B11").Value = cCnt
assigns the (only) value stored in cCnt to the same range over and over. So it's getting (possibly) different values in each iteration of the loop, but you're only seeing the last one.
Perhaps what you intended to do is something like:
Worksheets("Sheet3").Range("B" & iloop + 1).Value = cCnt
So, in the first iteration of the loop (when iLoop=1), it will assign the value in cCnt to Cell B2. When iLoop=2, it will assign cCnt to B3, etc...
More Information:
VBA For Loop – A Complete Guide

How to remove a certain value from a table that will vary in size in Excel

I'm new to the community and I apologize if there is a thread elsewhere, but I could not find it!
I'm currently diving into VBA coding for the first time. I have a file that I dump into a worksheet that currently I'm manually organizing and pushing out. When put into the worksheet, it delimits itself across the cells. This dump file will have varying row and column lengths every time I get it in a given day and dump into a work sheet. For example, one day it may be twenty rows and one day it may be thirty.
A certain roadblock in my VBA code creation process has presented itself. I'm trying to create a code that will parse through the worksheet to remove any time a certain value appears (See below image - I'm referring to the (EXT)). After doing so I'm trying to concatenate the cells in the row up until there is a space (which with the rows that have (EXT), there usually isn't a space after until the (EXT) is removed).
The code I made works for now but I recognize it's not very efficient and not reliable if the names extend longer than two cells. I was hoping someone on here could provide me with guidance. So, I'm looking for two things:
For the code to scan the whole active used range of the table and remove (EXT). As it may appear in various columns.
A way to concatenate the cells in every row in the active range from A to the cell before a blank cell
Keep in mind I have no coding background, I'm learning and I'm not familiar with VBA terms and whatnot all that much just yet - so if you could please explain in laymen's terms I'd appreciate it. I hope all of this makes sense... Thanks in advance!
This is just an example of part of what the dump code looks like, so my code probably doesn't match with the example below - I just wanted to provide a visual:
http://i.imgur.com/IwDDoYd.jpg
The code I currently have:
Sub DN_ERROR_ORGANIZER()
' Removes any (EXT) in Column 3 in actual dump data file
For i = 200 To 1 Step -1
If (Cells(i, 3).value = "(EXT)") Then
Cells(i, 3).Delete Shift:=xlToLeft
End If
Next i
' Removes any (EXT) in Column 4 in actual dump data file
For j = 200 To 1 Step -1
If (Cells(j, 4).value = "(EXT)") Then
Cells(j, 4).Delete Shift:=xlToLeft
End If
Next j
' Removes any (EXT) in Column 5 in actual dump data file
For k = 200 To 1 Step -1
If (Cells(k, 5).value = "(EXT)") Then
Cells(k, 5).Delete Shift:=xlToLeft
End If
Next k
' Places a new column before A and performs a concatenate on cells B1 and C1 to
' form a name, then copies all through column A1 to repeat on each row
Columns("A:A").Select
Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
Range("A1").Select
ActiveCell.FormulaR1C1 = "=PROPER(CONCATENATE(RC[1],"", "", RC[2]))"
Range("A1").Select
Selection.AutoFill Destination:=Range("A1:A51")
Range("A1:A51").Select
End Sub
edited: to keep the comma after the first "name" only
this should do:
Sub main()
Dim cell As Range
With Worksheets("names")
With Intersect(.UsedRange, .Range("A1", .Cells(.Rows.Count, 1).End(xlUp)).EntireRow)
For Each cell In .Rows
cell.Cells(1, 2).Value = Replace(Replace(Replace(Join(Application.Transpose(Application.Transpose(cell.Value)), " "), " ", " "), " (EXT)", ""), " ", ", ", , 1)
Next cell
.Columns(1).FormulaR1C1 = "=PROPER(RC[1])"
.Columns(1).Value = .Columns(1).Value
.Offset(, 1).Resize(, .Columns.Count - 1).ClearContents
End With
End With
End Sub
just remember to change "names" to you actual worksheet name
edited 2:
code for stopping cells to be processed at every line at the last one before the first blank one
Sub main()
Dim cell As Range, dataRng As Range
With Worksheets("names") '<--| change "names" to you actual worksheet name
Set dataRng = Intersect(.UsedRange, .Range("A1", .Cells(.Rows.Count, 1).End(xlUp)).EntireRow)
For Each cell In dataRng.Columns(1).Cells
cell.Offset(, 1).Value = Replace(Replace(Replace(Join(Application.Transpose(Application.Transpose(.Range(cell, cell.End(xlToRight)).Value)), " "), " ", " "), " (EXT)", ""), " ", ", ", , 1)
Next cell
With dataRng
.Columns(1).FormulaR1C1 = "=PROPER(RC[1])"
.Columns(1).Value = .Columns(1).Value
.Offset(, 1).Resize(, .Columns.Count - 1).ClearContents
End With
End With
End Sub
I believe you are quite close to achieve what you are asking for and, based on your request, I will not give you a solution but some guidance to complete it by yourself.
First 3 loops: You could simplify by having a single set of nested loops: An outer loop running from 3 to 5, an inner loop running from 200 to 1; the outer loop will run over index, say "p", the inner over index, say "q", and your reference to cells would become Cells(q,p). If you need to run this over more than 3 rows, just start the outer loop from, say, 3 and till, say 10000 (being 10000 the maximal number of rows your data may display) and add a condition that if the first cell of the row is empty, you exit the outer loop.
The second part (this is what I understood) is to take the 2-3 first cells and concatenate them into a new cell (i.e. the column you add at the left). Once again, you can just loop over all your rows (much the same as in the outer loop mentioned above), except that now you will be looking at the cells in columns 2-4 (because you added a column at the left). The same exit condition as above can be used.
I'm not sure if this is what you were looking for, but this is what I understood you were looking for.
After reading user3598756's answer, I realized that I missed the boat with my original answer.
Sub DN_ERROR_ORGANIZER()
Dim Target As Range
Set Target = Worksheets("Sheet1").UsedRange
Target.Replace "(EXT)", ""
With Target.Offset(0, Target.Columns.Count).Resize(, 1)
.FormulaR1C1 = "=PROPER(C1&"", ""&TEXTJOIN("" "",TRUE,RC[-" & (Target.Columns.Count - 1) & "]:RC[-1]))"
.Value = .Value
End With
Target.Delete
End Sub
UPDATE
If you are running an older version of Excel that doesn't support TEXTJOIN then use this:
Sub DN_ERROR_ORGANIZER()
Dim Data
Dim x As Long, y As Long
Dim Target As Range
Dim Text As String
Set Target = Worksheets("Sheet1").UsedRange
Target.Replace "(EXT)", ""
Data = Target.Value
For x = 1 To Target.Rows.Count
Data(x, 1) = Data(x, 1)
For y = 2 To Target.Columns.Count
If Data(x, y) <> vbNullString Then Text = Text & " " & Data(x, y)
Next
If Len(Text) Then Data(x, 1) = Data(x, 1) & "," & Text
Text = vbNullString
Next
Target.ClearContents
Target.Columns(1).Value = Data
End Sub

VBA Look through List

I've got the following code which gets the word dividend from a column and then takes the whole row and copy pastes it to a new sheet.
Sub SortActions()
Dim i&, k&, s$, v, r As Range, ws As Worksheet
Set r = [index(a:a,match("###start",a:a,),):index(a:a,match("###end",a:a,),)].Offset(, 6)
k = r.Row - 1
v = r
For i = 1 To UBound(v)
If LCase$(v(i, 1)) = "dividend" Then
s = s & ", " & i + k & ":" & i + k
End If
Next
s = Mid$(s, 3)
If Len(s) Then
Set ws = ActiveSheet
With Sheets.Add(, ws)
ws.Range(s).Copy .[a1]
Rows("1:1").Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Sheets("20140701_corporate_action_servi").Select
Rows("2:2").Select
Selection.Copy2
Range("C32").Select
Sheets("Sheet11").Select
ActiveSheet.Paste
End With
End If
End Sub
Is there a way to make this dynamic. So if I want to search for more than word. For example if I have several rows with dividends and special dividends -> it would take all rows of dividends and all rows of special dividends and put them in separate sheets. I have tried ti with recording a macro it doesn't work as the words can differ. Maybe getting the content into a list would work. Please assist . Thanks
As suggested by #Macro Man , I am submitting images of an example sheet and sheet after filter with a simple macro for filtering one field. Please all credit to #Macro Man, it is for illustration in a simple way.
Simple code as follows.
Sub Filter1Field()
With Sheet1
.AutoFilterMode = False
With .Range("A1:H13")
.AutoFilter
.AutoFilter Field:=5, Criteria1:="Dividend"
End With
End With
End Sub
*****UPDATE*******
If your other criteria such as "Sp. Dividend" is other field but on the same row as shown in the image appended and you wish to copy to other sheet you can use the code given below. Another image shows results obtained on sheet2. You can adopt the code to your requrements.
You can use this code:
Sub Test2()
Dim LastRow As Long
Sheets("Sheet2").UsedRange.Offset(0).ClearContents
With Worksheets("Sheet1")
.Range("A1:H13").AutoFilter
.Range("A1:H13").AutoFilter field:=5, Criteria1:="Dividend"
.Range("A1:H13").AutoFilter field:=6, Criteria1:="=Sp. Dividend"
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A1:A" & LastRow).SpecialCells(xlCellTypeVisible).EntireRow.Copy _
Destination:=Sheets("Sheet2").Range("A1")
End With
End Sub

Change a cell's format to boldface if the value is over 500

I am using Excel 2010 and trying to add a bunch of rows placing the sum of columns A and B in column C. If the sum is over 500 I would then like to boldface the number in column C. My code below works works mathematically but will not do the bold formatting. Can someone tell me what I am doing wrong? Thank you.
Public Sub addMyRows()
Dim row As Integer 'creates a variable called 'row'
row = 2 'sets row to 2 b/c first row is a title
Do
Cells(row, 3).Formula = "=A" & row & "+B" & row 'the 3 stands for column C.
If ActiveCell.Value > 500 Then Selection.Font.Bold = True
row = row + 1
'loops until it encounters an empty row
Loop Until Len(Cells(row, 1)) = 0
End Sub
Pure VBA approach:
Public Sub AddMyRows()
Dim LRow As Long
Dim Rng As Range, Cell As Range
LRow = Range("A" & Rows.Count).End(xlUp).Row
Set Rng = Range("C2:C" & LRow)
Rng.Formula = "=A2+B2"
For Each Cell In Rng
Cell.Font.Bold = (Cell.Value > 500)
Next Cell
End Sub
Screenshot:
An alternative is conditional formatting.
Hope this helps.
Note: The formula in the block has been edited to reflect #simoco's comment regarding a re-run of the code. This makes the code safer for the times when you need to re-run it. :)