Find word into cell - vba

Excel - VBA
I was wondering how to find a word into a Excel range of rows using VBA. Ex. "word to be found", this is not just the cell value but a word into a string. For instance, the way to find the word "network" into the string "Need help to map network printer".
Sub SearchForSfb()
Dim LSearchRow As Integer
Dim LCopyToRow As Integer
On Error GoTo Err_Execute
'Start search in row 1
LSearchRow = 1
'Start copying data to row 2 in Open (row counter variable)
LCopyToRow = 2
While Len(Range("E" & CStr(LSearchRow)).Value) > 0
'If value in column E = "word to be found", copy entire row to Open
If Range("E" & CStr(LSearchRow)).Value = "word to be found" Then
'Select row in Data to copy
Rows(CStr(LSearchRow) & ":" & CStr(LSearchRow)).Select
Selection.Copy
'Paste row into SFB in next row
Sheets("SFB").Select
Rows(CStr(LCopyToRow) & ":" & CStr(LCopyToRow)).Select
Sheets("SFB").Paste
'Move counter to next row
LCopyToRow = LCopyToRow + 1
'Go back to Data to continue searching
Sheets("Data").Select
End If
LSearchRow = LSearchRow + 1
Wend
'Position on cell A3
Application.CutCopyMode = False
Range("A3").Select
MsgBox "All matching data has been copied."
Exit Sub
Err_Execute:
MsgBox "An error occurred."
End Sub

Use a simple loop
Sub Button1_Click()
Dim ws As Worksheet
Dim sh As Worksheet
Dim lstRw As Long
Dim rng As Range
Dim s As String
Dim c As Range
s = "* network *"
Set ws = Sheets("Data")
Set sh = Sheets("SFB")
With ws
lstRw = .Cells(.Rows.Count, "E").End(xlUp).Row
Set rng = .Range("E2:E" & lstRw)
End With
For Each c In rng.Cells
If c.Value Like s Then
c.EntireRow.Copy sh.Cells(sh.Rows.Count, "A").End(xlUp).Offset(1)
End If
Next c
End Sub
Or you can use a filter macro
Sub FiltExample()
Dim ws As Worksheet, sh As Worksheet
Dim rws As Long, rng As Range
Set ws = Sheets("Data")
Set sh = Sheets("SFB")
Application.ScreenUpdating = 0
With ws
rws = .Cells(.Rows.Count, "E").End(xlUp).Row
.Range("E:E").AutoFilter Field:=1, Criteria1:="=*network*"
Set rng = .Range("A2:Z" & rws).SpecialCells(xlCellTypeVisible)
rng.EntireRow.Copy sh.Cells(sh.Rows.Count, "A").End(xlUp).Offset(1)
.AutoFilterMode = False
End With
End Sub

Related

Changing the search from one cell to the entire sheet

I've tried changing everywhere there was a cell to a range and other things but I can't figure it out. I'd like for the code to search the entire sheet, instead of one cell, for these names and paste the information of the cell to the right of it to the other sheet.
Option Explicit
Private Sub CommandButton1_Click()
Dim ws As Worksheet, myCounter As Long
Dim erow As Long, myValue As Long
Dim nextValue As Long
For Each ws In ThisWorkbook.Sheets
With ws
Select Case .Range("C3").Value
Case "David", "Andrea", "Caroline"
myCounter = 1 ' raise flag >> found in at least 1 sheet
' get first empty row in "Report" sheet
erow = Worksheets("Report").Cells(Worksheets("Report").Rows.Count, 1).End(xlUp).Offset(1, 0).Row
Worksheets("Report").Cells(erow, 1) = .Range("C3").Value
End Select ' Select Case .Range("C3").Value
End With
Next ws
If myCounter = 0 Then
MsgBox "None of the sheets contains the names " & Chr(10) & " 'David', 'Andrea', 'Caroline' in cell C3 ", vbInformation, "Not Found"
End If
End Sub
You can use Application.Match with array version. Substitute this for your loop:
Dim ar, r
For Each ws In ThisWorkbook.Sheets
ar = Application.match(Array("David", "Andrea", "Caroline"), ws.Columns("C"), 0)
For Each r In ar
If Not IsError(r) Then
myCounter = 1 ' raise flag >> found in at least 1 sheet
erow = Worksheets("Report").Cells(Worksheets("Report").Rows.Count, 1).End(xlUp).Offset(1, 0).row
Worksheets("Report").Cells(erow, 1) = ws.Range("C" & r).value
Worksheets("Report").Cells(erow, 2) = ws.Range("D" & r).value
End If
Next r
Next ws
Notice though, that this will find you only one match for each word, the first one. If each word can be repeated many times and you want to find all matches, it will need some modification.
Multiple rows and multiple columns would be better served by the Find command.
Option Explicit
Private Sub CommandButton1_Click()
Dim ws As Worksheet, bFound As Boolean, rFound As Range
Dim a As Long, aNames As Variant
aNames = Array("David", "Andrea", "Caroline")
For Each ws In ThisWorkbook.Worksheets
'If ws.Name <> Worksheets("Report").Name Then
If ws.Name = "Sheet7" Then
With ws.Range("A1:E30").Cells
For a = LBound(aNames) To UBound(aNames)
Set rFound = .Find(What:=aNames(a), MatchCase:=False, LookAt:=xlWhole, SearchFormat:=False)
If Not rFound Is Nothing Then
bFound = True
With Worksheets("Report")
.Cells(.Rows.Count, 1).End(xlUp).Offset(1, 0) = rFound.Value
End With
End If
Next a
End With
End If
Next ws
If Not bFound Then
MsgBox "None of the sheets contains the names " & Chr(10) & _
"'" & Join(aNames, "', '") & "' in cells A1:E30.", vbInformation, "Not Found"
End If
End Sub

VBA, New Sheet, Formating Cells

I have the follow VBA script that does an advanced filter and populates to a new sheet. I would like to get the results in order on my new sheet.
So for example Sheet 1 results would be populated in C2, Sheet 2 C3, Sheet 3 in C4. But if Sheet 2 has no results Sheet 3 will populate in C3 instead. Anyone know of any work-around? I need the results to be correspond with the sheet. Could be a simple range formula? VBA newbie here.
Sub louis4()
Dim wks As Excel.Worksheet
Dim wksSummary As Excel.Worksheet
'----------------------------------------------------------------------------------
'edited so it shows in the 3rd column row +1. Add the header and sheet name macro to this
On Error Resume Next
Set wksSummary = Excel.ActiveWorkbook.Worksheets("Unique data")
On Error GoTo 0
If wksSummary Is Nothing Then
Set wksSummary = Excel.ActiveWorkbook.Worksheets.Add
wksSummary.Name = "Unique data"
End If
'Iterate through all the worksheets, but skip [Summary] worksheet.
For Each wks In Excel.ActiveWorkbook.Worksheets
With wksSummary
If wks.Name <> .Name Then
If Application.WorksheetFunction.CountA(wks.Range("C:C")) Then
Dim r As Range
' Get the first cell of our destination range...
Set r = .Cells(.Cells(.Rows.Count, 3).End(xlUp).Row + 1, 3)
' Perform the unique copy...
If WorksheetFunction.CountA(wks.Range("C:C")) > 1 Then
wks.Range("C:C").AdvancedFilter xlFilterCopy, , r, True
End If
' Remove the first cell at the destination range...
r.Delete xlShiftUp
End If
End If
End With
Next wks
'Headers and sheet names
Range("A1").Value = "File Name "
Range("B1").Value = "Sheet Name "
Range("C1").Value = "Column Name"
Dim intRow As Long: intRow = 2
For i = 1 To Sheets.Count
If Sheets(i).Name <> ActiveSheet.Name Then
Cells(intRow, 2) = Sheets(i).Name
Cells(intRow, 1) = ActiveWorkbook.Name
intRow = intRow + 1
End If
Next i
End Sub
As per what we discussed in the comments, I believe you want this:
Sub louis4()
Dim wks As Excel.Worksheet
Dim wksSummary As Excel.Worksheet
'----------------------------------------------------------------------------------
'edited so it shows in the 3rd column row +1. Add the header and sheet name macro to this
On Error Resume Next
Set wksSummary = Excel.ActiveWorkbook.Worksheets("Unique data")
On Error GoTo 0
If wksSummary Is Nothing Then
Set wksSummary = Excel.ActiveWorkbook.Worksheets.Add
wksSummary.Name = "Unique data"
End If
'Iterate through all the worksheets, but skip [Summary] worksheet.
For Each wks In Excel.ActiveWorkbook.Worksheets
With wksSummary
If wks.Name <> .Name Then
If Application.WorksheetFunction.CountA(wks.Range("C:C")) Then
Dim r As Range
' Get the first cell of our destination range...
Set r = .Cells(.Cells(.Rows.Count, 3).End(xlUp).Row + 1, 3)
' Perform the unique copy...
If WorksheetFunction.CountA(wks.Range("C:C")) > 1 Then
wks.Range("C:C").AdvancedFilter xlFilterCopy, , r, True
else
r = "N/A"
End If
' Remove the first cell at the destination range...
r.Delete xlShiftUp
End If
End If
End With
Next wks
'Headers and sheet names
Range("A1").Value = "File Name "
Range("B1").Value = "Sheet Name "
Range("C1").Value = "Column Name"
Dim intRow As Long: intRow = 2
For i = 1 To Sheets.Count
If Sheets(i).Name <> ActiveSheet.Name Then
Cells(intRow, 2) = Sheets(i).Name
Cells(intRow, 1) = ActiveWorkbook.Name
intRow = intRow + 1
End If
Next i
End Sub
Sub louis4()
Dim wks As Excel.Worksheet
Dim wksSummary As Excel.Worksheet
Dim LastCellInColumn As Range
Dim NewLastCellInColumn as Range
On Error Resume Next
Set wksSummary = Excel.ActiveWorkbook.Worksheets("Unique data")
On Error GoTo 0
If wksSummary Is Nothing Then
Set wksSummary = Excel.ActiveWorkbook.Worksheets.Add
wksSummary.Name = "Unique data"
End If
With wksSummary
'Headers and sheet names
.Range("A1").Value = "File Name "
.Range("B1").Value = "Sheet Name "
.Range("C1").Value = "Column Name"
'Iterate through all the worksheets, but skip [Summary] worksheet.
For Each wks In Excel.ActiveWorkbook.Worksheets
If wks.Name <> .Name Then
' Get the first cell of our destination range...
Set LastCellInColumn = .Cells(.Rows.Count, 3).End(xlUp).offset(1,0)
If Application.WorksheetFunction.CountA(wks.Range("C:C")) > 1 Then
wks.Range("C:C").AdvancedFilter xlFilterCopy, , LastCellInColumn, True
' Remove the first cell at the destination range...
' because it contains the header text from the source sheet
LastCellInColumn.Delete xlShiftUp
else
LastCellInColumn.value = "No data found
End If
Set NewLastCellInColumn = .Cells(.Rows.Count, 3).End(xlUp).offset(1,0)
.cells(LastCellInColumn.offset(-1,0), NewLastCellInColumn.offset(-1,0)).value = wks.Name
.cells(LastCellInColumn.offset(-2,0), NewLastCellInColumn.offset(-2,0)).value = ActiveWorkbook.Name
End If
Next wks
End With
End Sub

Combine sheets in excel

I have a workbook that has 50 plus sheets in it. What I am looking to do is to combine all the sheets into 1 master sheet with the following criteria:
1. Each sheet in its own column
2. The sheet name as the header of that column
Each sheet has one column (A) with data in it but various amount of rows. There are no headers in the sheets.
From my research I have found that I can combine all the sheets into 1 column, but that does not help.
Any help would be appreciated and thank you
Try this:
Dim J As Integer
On Error Resume Next
Sheets(1).Select
Worksheets.Add
Sheets(1).Name = "Combined"
Sheets(2).Activate
Range("A1").EntireRow.Select
Selection.Copy Destination:=Sheets(1).Range("A1")
For J = 2 To Sheets.Count
Sheets(J).Activate
Range("A1").Select
Selection.CurrentRegion.Select
Selection.Offset(1, 0).Resize(Selection.Rows.Count - 1).Select
Selection.Copy Destination:=Sheets(1).Range("A65536").End(xlUp)(2)
Next
It will help you..
This is a little ugly but it will do what you want. Just change Set targetWS = Sheets("Sheet1") to be the sheet that you are putting all the data.
Sub combineSheets()
Dim sourceWs As Worksheet
Dim targetWs As Worksheet
Dim targetCol As Integer
Dim endRow As Long
'This is the sheet where the data will end up
Set targetWs = Sheets("Sheet1")
'This is the first column to start pasting into
targetCol = 1
'Loop through the worksheets in the workbook
For Each sourceWs In ThisWorkbook.Worksheets
'grab the data from each sheet, bu not the target sheet
If sourceWs.Name <> targetWs.Name Then
'find last row in source sheet
endRow = sourceWs.Range("A999999").End(xlUp).Row()
'paste data and name
targetWs.Range(targetWs.Cells(2, targetCol), targetWs.Cells(endRow, targetCol)) = sourceWs.Range("A1:A" & endRow).Value
targetWs.Cells(1, targetCol).Value = sourceWs.Name
'next column
targetCol = targetCol + 1
End If
Next sourceWs
End Sub
This may help
Option Explicit
Sub CopyRangePaste()
'copies and pastes what is required
Dim wshResult As Worksheet
Dim wsh As Worksheet
Dim msg As String ' alert message
Dim iCounter As Integer
If Worksheets.Count < 2 Then 'if there is only 1 worksheet exits sub
msg = "There is only 1 worksheet." & vbCrLf
msg = msg & "Try again with a different workbook."
MsgBox msg, vbCritical
Exit Sub
End If
Set wshResult = ActiveWorkbook.Sheets.Add
iCounter = 0
For Each wsh In ActiveWorkbook.Worksheets
If wsh.Name <> wshResult.Name Then 'checks if the newly created sheet is not operated on
iCounter = iCounter + 1
wshResult.Cells(1, iCounter) = wsh.Name
wsh.Range(wsh.UsedRange.Find("*").CurrentRegion.Address).Copy _
wshResult.Cells(2, iCounter) 'copies the current region
End If
Next wsh
MsgBox iCounter & " sheets"
End Sub

copy a filtered range to 2nd row where col headings match

i need to copy data from one sheet to another and paste into the next available row where the column headings match.
I am having difficulty creating the range to copy into.
this seems to be the issue -
rng1.SpecialCells(xlCellTypeVisible).Copy Destination:=Sheets("Combined Totals").Range(tCell.Offset(1) & lRow)
i ahve tried creating the destination to paste to using Cells and Range, but i can't seem to add variables into the syntax correctly.
What am i doing wrong?
Set this to the relevant worksheet
Set ws = ThisWorkbook.Sheets("OPT 1 Total")
With ws
'~~> Find the cell which has the name
Set sCell = .Range("A1:Z1").Find("MN")
Set tCell = Sheets("Combined Totals").Range("A1:Z1").Find("MN")
'~~> If the cell is found
If Not sCell Is Nothing Then
'~~> Get the last row in that column and check if the last row is > 1
lRow = .Range(Split(.Cells(, sCell.Column).Address, "$")(1) & .Rows.Count).End(xlUp).Row
If lRow > 1 Then
'~~> Set your Range
Set rng1 = .Range(sCell.Offset(1), .Cells(lRow, sCell.Column))
'bCell.Offset(1).Activate
Debug.Print tCell.Address
rng1.SpecialCells(xlCellTypeVisible).Copy Destination:=Sheets("Combined Totals").Range(tCell.Offset(1) & lRow)
'Cells(2, 1).Resize(rng1.Rows.Count) '
'~~> This will give you the address
Debug.Print rng1.Address
End If
End If
End With
EDIT2: parameterized....
Sub CopyAll()
TransferToTotals "OPT 1 Total", Array("MN", "TX", "CA")
TransferToTotals "OPT 2 Total", Array("MN", "TX", "CA")
End Sub
Sub TransferToTotals(srcSheet As String, arrHeaders)
Dim ws As Worksheet, sCell As Range, tCell As Range, lstCell As Range
Dim wsd As Worksheet, i As Long, arrHeadings
Set wsd = ThisWorkbook.Sheets("Combined Totals")
On Error Resume Next
Set ws = ThisWorkbook.Sheets(srcSheet)
On Error GoTo 0
If ws Is Nothing Then
Debug.Print "Source sheet '" & srcSheet & "' not found!"
Exit Sub
End If
For i = LBound(arrHeaders) To UBound(arrHeaders)
With ws
Set sCell = .Range("A1:Z1").Find(arrHeaders(i))
Set tCell = wsd.Range("A1:Z1").Find(arrHeaders(i))
If Not sCell Is Nothing And Not tCell Is Nothing Then
Set lstCell = .Cells(.Rows.Count, sCell.Column).End(xlUp)
If lstCell.Row > 1 Then
'EDIT - paste values only...
.Range(sCell.Offset(1), lstCell).SpecialCells( _
xlCellTypeVisible).Copy
wsd.Cells(Rows.Count, tCell.Column).End(xlUp) _
.Offset(1, 0).PasteSpecial xlPasteValues
End If
Else
Debug.Print "Couldn't find both '" & _
arrHeaders(i) & "' headers"
End If
End With
Next i
End Sub

Excel - Copy specified columns to a new sheet based on data in a column

I require assistance with the following please:
I need to filter a Range A9 - A32 for any data in column G.
Then i need to copy the data, but only columns A - E & G to sheet 2.
then delete the filtered data and return back to non filtered view.
I have tried the following without success:
Dim shSrc As Worksheet
Dim shDst As Worksheet
Dim rSrc As range
Dim rDst As range
Dim range
Dim numCol As Long ' number of columns to copy
On Error GoTo EH
range = ("A:E,G:G")
' select source and dest sheets
Set shSrc = ActiveWorkbook.Worksheets("Active Snag List")
Set shDst = ActiveWorkbook.Worksheets("Snag History")
' Select initial rows
Set rSrc = shSrc.Cells(9, 7)
Set rDst = shDst.Cells(2, 1)
' loop over source
Do While rSrc <> ""
' Test Source row, Qty = 0 and Name is not blank
With rSrc
If .Offset(0, 2) = 0 And .Value <> "" Then
'Copy
.Resize(1, range).Copy rDst.Resize(1, range)
Set rDst = rDst.Offset(1, 0)
End If
End With
Set rSrc = rSrc.Offset(1, 0)
Loop
Exit Sub
EH:
MsgBox "Error " & Err.Description
Thank you in advance!
To get your code working , replace the IF section with this
If .Offset(0, 2) = 0 And .Value <> "" Then
'Copy
'Cells A:E
rDst.Resize(1, 5).Value = .EntireRow.Cells(1, 1).Resize(1, 5).Value
' Cell G
rDst.Offset(0, 6).Value = .Value
Set rDst = rDst.Offset(1, 0)
End If
Why not use Autofilter rather than looping through cells? It will me much faster. See this example.
CODE(TRIED AND TESTED)
Option Explicit
Sub Sample()
Dim shSrc As Worksheet, shDst As Worksheet
Dim rDst As range, rng As range, rngtocopy As range
Dim lastrow As Long
On Error GoTo EH
'~~> Select source and dest sheets
Set shSrc = ThisWorkbook.Worksheets("Active Snag List")
Set shDst = ThisWorkbook.Worksheets("Snag History")
'~~> Select initial rows
Set rDst = shDst.Cells(2, 1)
With shSrc
'~~> Remove any filters
.AutoFilterMode = False
'~~> Get the last row of Col G
lastrow = .range("G" & .Rows.Count).End(xlUp).Row
With .range("A8:G" & lastrow)
'~~> Filter G Col for non blanks
.AutoFilter Field:=7, Criteria1:="<>"
'~~> Get the offset(to exclude headers)
Set rng = .Offset(1, 0).SpecialCells(xlCellTypeVisible)
'~~> Remove Col F from the resulting range
Set rngtocopy = Union(shSrc.range(Replace(rng.Address, "G", "E")), _
shSrc.range(Replace(rng.Address, "A", "G")))
'~~> Copy cells to relevant destination
rngtocopy.Copy rDst
'~~> Delete the filtered results
rng.EntireRow.Delete
End With
'~~> Remove any filters
.AutoFilterMode = False
End With
Exit Sub
EH:
MsgBox "Error " & Err.Description
End Sub
SNAPSHOTS
Sheet 1 before the macro runs
Sheet 2 after the macro runs
Sheet 1 after the macro runs