Excel VBA. Search if Cell Containing Specific Text from multiple Sheets And ONLY Certain Parts of the found cell - excel

Thanks for taking time to take a look at the problems i am facing..
Been searching and testing for quite a bit but still didnt manage to find out what went wrong.
Right now i have no idea what went wrong.
Below is the current code
this is sheets to be searched
Red area is where the model number is enter, and price is from search results
Sub Search()
Dim LR As Long, i2 As Long
totalsheets = Worksheets.Count
For i = 1 To totalsheets
If Worksheets(i).Name <> "Main" Then
lastrow = Worksheets(i).Cells(Rows.Count, 1).End(xlUp).Row
For j = 2 To lastrow
If UCase(Worksheets(i).Range("C" & j).Value) Like "*A1-1-35-01*" Then
Worksheets("Main").Activate
Worksheets("Main").Range(k, 4).Value = Worksheets("Main").Range("A", j)
lastrow = Worksheets("Main").Cells(Rows.Count, 1).End(xlUp).Row
End If
Next
End If
Next
End Sub

Related

Compare Cell formatting

I´ve developed a small macro on Excel using VBA, which compares the information on column C and copies the formating information contained on column F on sheet(3).
The code is working well, however, I´m trying to optimize it. I would like to avoid copying the formating when a given cell already contains the intended formating. Something like:
If Range("C7").Offset(i, 0).***FORMATING*** = Sheets(3).Range("F7").Offset(j, 0).***FORMATING*** Then
Unfortunately, I haven't been able to identify the attribute that defines the formatting of a cell.
Please see below the current code I have:
Sub Contract()
Application.ScreenUpdating = False
Dim i As Integer, j As Integer, Lastrow As Integer, Lastrow2 As Integer
Sheets(1).Activate ' activa a sheet(1)
Lastrow = Cells(Rows.Count, "C").End(xlUp).Row
Lastrow2 = Sheets(3).Cells(Rows.Count, "F").End(xlUp).Row
For i = 0 To Lastrow - Range("c7").Row
For j = 0 To Lastrow2 - Range("F7").Row
If Range("C7").Offset(i, 0).Value = Sheets(3).Range("F7").Offset(j, 0).Value Then
Sheets(3).Range("F7").Offset(j, 0).Copy
Range("C7").Offset(i, 0).PasteSpecial Paste:=xlPasteFormats
Exit For
End If
Next j
Next i
End Sub
Thank you for the help.

Autofil cell with the month number if adjacent cell contains date

I'm looking for a smoother solution for below code. The task is if column O is not empty, then check if AH is empty. If AH is not empty (then it contains a date) I need to get the number of the month from this date to column AI (right next to AH).
I'm new to coding and so far the below is what I've got but this doesn't seem the perfect solution as it is simply adding the formula to and I suppose this could be also done by a loop.
Many thanks in advance.
Sub d_month()
Dim r As Range
Dim LastRow As Long
With Application.ActiveSheet
LastRow = .Cells(.Rows.Count, "O").End(xlUp).Row
For Each r In .Range("O2:O" & LastRow)
If r.Value <> "" Then
r.Offset(0, 20).Value = "=IF(RC[-1]="""","""",MONTH(RC[-1]))"
End If
Next r
End With
End Sub
There are various ways to do this. You can use Excel Formulas, Worksheet_Change or as shown below.
Few suggestions (not a hard and fast rule. Just my personal opinion).
Keep the code simple and easy to understand.
Avoid using Offset unless and until it is really important. This way you will know which cell is being handled just by looking at it. With offset, you will have to count and ensure that it is the right cell.
Use simple For Loops as shown below.
Is this what you are trying?
Option Explicit
Sub Sample()
Dim ws As Worksheet
Dim lRow As Long
Dim i As Long
'~~> Change this to relevant sheet
Set ws = Sheet1
With ws
lRow = .Range("O" & .Rows.Count).End(xlUp).Row
For i = 2 To lRow
'~~> Check if O and AH are not empty
If Len(Trim(.Range("O" & i).Value)) <> 0 And _
Len(Trim(.Range("AH" & i).Value)) <> 0 Then
'~~> Write to AI
.Range("AI" & i).Value = Month(.Range("AH" & i).Value)
End If
Next i
End With
End Sub

Excel VBA Delete Rows Containing certain text. Code not working

I have a macro that opens a workbook. I want it to then look into column C and if it finds anything with the text "Draft", delete the entire row. This is my code which does not appear to give me any errors but it does not delete the rows like I want. What am I missing?
enter code here
Dim i As Long
Dim FinalRow As Long
FinalRow = Cells(Rows.Count, 1).End(xlUp).Row
With Worksheets("Archer Search Report")
For i = 2 To FinalRow
If Range("C" & i).Value = "Draft" Then
Rows(i).Delete
End If
Next i
End With
Try this:
Sub DeleteRows()
Dim i As Long, finalRow As Long
finalRow = Cells(Rows.Count, 1).End(xlUp).Row
With Worksheets("Archer Search Report")
For i = finalRow To 2 Step -1
If Range("C" & i).Value = "Draft" Then
Range("C" & i).EntireRow.Delete
End If
Next i
End With
End Sub
Notes:
It's best to work backwards (Step -1) when deleting otherwise it messes with the row count
I prefer EntireRow.Delete

VBA- Copying Values from one cell to another offset cell

I am trying to go through row 6 and from column 1 to 26 and search for the sentence Earned Cumulative Hours. Once that is done then I am trying to go from row 8 to the last row(30 in this case) for the column that has Earned Cumulative Hours in row 6.
Then I am trying to paste the values of the cells from this column to 2 cells left in the same row. But I keep getting errors and the code doesn't work.
Can someone please point me in the right direction ? Thanks
Sub project()
Dim lastrow As Long
Dim i As Long
Dim j As Long
lastrow = Sheets("Progress").Cells(Rows.Count, 26).End(xlUp).Row
For j = 1 To 26
If Cells(6, j) = "Earned Cumulative Hours" Then
For i = 8 To lastrow
Cells(i, j).Copy
Cells(i, j).Offset(0, -2).Select
Selection.PasteSpeical Paste:=xlPasteValues
Next i
End If
Next j
End Sub
There are a few problems I can see straight away with your code. Firstly if you are offsetting back two columns .Cells(i, j).Offset(0, -2) then you will be overwriting existing values. If this is what you intend to do then weird but ok.
The next issue is that you have a problem if 'Earned Cumulative Hours' is in Column A. If this is your case Excel will be most unhappy trying to offset two columns to the left and will give an error.
In this case instead of copying and pasting it will be more efficient to set values in one column to the other which you can see in my code. Finally, your Cell references will be valid for the active sheet only. You need to qualify what worksheet you interest in as shown in my code. I normally put this at the start of the code if it is a self contained block.
You could also eliminate the i loop and set ranges of values at a time but we'll save that for next time!
I haven't test this code but it should be fine.
Sub projectawesome()
Dim lastrow as Long, i as Long, j as Long
'Qualify the sheet (assuming its in the activeworkbook)
With Sheets("Progress")
lastrow = .Cells(.Rows.Count, 26).End(xlUp).Row
'I've changed this to column three to prevent offset errors.
For j = 3 to 26
If .Cells(6, j) = "Earned Cumulative Hours" Then
For i = 8 to lastrow
'Assuming overwriting data is ok.
'No need to copy and paste
.Cells(i, j - 2).Value = .Cells(i, j).Value
Next i
End If
Next
End With
End Sub
Try this and we can get rid of those selects
Sub project()
Dim lastrow As Long
Dim i As Long
Dim j As Long
lastrow = Sheets("Progress").Cells(Rows.Count, 26).End(xlUp).Row
For j = 1 To 26
If Cells(6, j) = "Earned Cumulative Hours" Then
For i = 8 To lastrow
Cells(i, j).Copy
With Cells(i, j)
.Offset(0, -2).PasteSpecial xlPasteValues
End With
Next i ' next row
End If
Next j ' next col
End Sub

faster way to loop through two sheets of 10000+ rows

This module goes through each cell in column a in sheet 2, and checks it with every cell in colmumn b in sheet2, if it matchs the "matches number" increases and is placed in a cell im sheet3. the ammount of data is huge and the module keeps on crashing, is there abetter way of doing this (maybe access, or a more efficient VBA module). Please note that I need to know the number of matches for each cell alone and not the total number of repetition.
Thanks in advance fellas!
Sub findpatterns()
Application.ScreenUpdating = False
Dim RowCount1 As Long, ClmnCount1 As Long
Dim RowCount2 As Long, ClmnCount2 As Long
Dim Crntrow As Long, Lastrow As Long
Dim Crntrow1 As Long, LastRow1 As Long
Dim Recordrow As Long
Recordrow = 1
RowCount1 = Sheets("sheet1").Cells(Rows.Count, "a").End(xlUp).Row
ClmnCount1 = Sheets("sheet1").Cells(1, Columns.Count).End(xlToLeft).Column
RowCount2 = Sheets("sheet2").Cells(Rows.Count, "a").End(xlUp).Row
ClmnCount2 = Sheets("sheet2").Cells(1, Columns.Count).End(xlToLeft).Column
Lastrow = RowCount1
LastRow1 = RowCount2
Crntrow1 = 1
Crntrow = 1
For Crntrow1 = 1 To LastRow1
'MsgBox "first loop is running"
For Crntrow = 1 To Lastrow
'MsgBox "second loop is running"
If (Sheets("sheet2").Cells(Crntrow1, "a").Value = Sheets("sheet1").Cells(Crntrow, "b").Value Or Sheets("sheet1").Cells(Crntrow, "b").Value = Sheets("sheet2").Cells(Crntrow1, "b").Value) And Not Sheets("sheet2").Cells(Crntrow1, "a").Value = "" Then
Sheets("sheet3").Cells(Crntrow1, "b").Value = Sheets("sheet3").Cells(Crntrow1, "b").Value + 1
'Sheets("sheet3").Cells(Crntrow1, "c").Value = Sheets("sheet2").Cells(Crntrow1, "g").Value
'MsgBox Material
Else
'MsgBox "no matches found"
End If
Next Crntrow
Next Crntrow1
End Sub
First off just a few comments on your code as it is not real easy to read.
You can get rid of some variables, ClmnCount(1,2) aren't used
RowCount(1,2) are only used to pass values directly to Lastrow so you don't really need them
By passing RowCount1>LastRow and RowCount2>LastRow1 you make it more confusing try to keep your numbering scheme consistant
It looks like you basically want a countif statement like this
=IF(Sheet2!A1="",0,COUNTIF(Sheet1!$B$1:$B$10000,Sheet2!A1)+COUNTIF(Sheet1!$B$1:$B$10000,Sheet2!B1))
Which counts the number of occurances in Sheet1 column B that match sheet2 A1 or B1 and does this for each row in column 2 (as long as sheet2 A1 has data in it).
By using this formula in a macro you can avoid the loop using something like the following. Which uses the formula, fills it down for all the rows you need and then copies the values over the formulas to freeze it. This should be a fair bit quicker then your double loop.
Sub findpatterns()
Dim LastRow1 As Long
Dim LastRow2 As Long
Application.ScreenUpdating = False
LastRow1 = Sheets("sheet1").Cells(Rows.Count, "a").End(xlUp).Row
LastRow2 = Sheets("sheet2").Cells(Rows.Count, "a").End(xlUp).Row
Sheets("sheet3").Range("A1").Formula = "=IF(Sheet2!A1="""",0,COUNTIF(Sheet1!$B$1:$B$" & LastRow1 & ",Sheet2!A1)+COUNTIF(Sheet1!$B$1:$B$" & LastRow1 & ",Sheet2!B1))"
Sheets("sheet3").Range("A1").AutoFill Destination:=Sheets("sheet3").Range("A1:A" & LastRow2)
Calculate
Sheets("sheet3").Range("A1:A" & LastRow2).Value = Sheets("sheet3").Range("A1:A" & LastRow2).Value
Application.ScreenUpdating = True
End Sub
When you have data that is this large and if it has many columns also, you may want to consider using a database (MSAccess, SQLServer etc).
That said, there are ways to speed up your code also. Excel objects like Cells, Ranges, Sheets etc are heavy with data about the size, color, borders, fill font etc that you don't likely need. Try using a variant to store the data ONLY like this:
Let the variable LastCol represent the last column in the data.
Dim myData as Variant
myData = Range(Sheets("Sheet2").Cells(1, 1), Sheets("Sheet2").Cells(LastRow, LastCol))
Note that I did NOT use the Set keyword. This will return the default value for the Range object (which is a variant containing only the data.
Now iterating: For i = LBound(myData, 1) to UBound(MyData, 1) should be faster.

Resources