Conditionally search in one sheet and copy the rows to another sheet - vba

I have a workbook called Open Case Report.xlsm with the sheets called RAW_Data and Formatted.
I want to create a macro that will search RAW_Data for a set of 2 names in column E and copy the entire row over to Formatted in a specific spot such as A1.
I have looked on here and found a few codes that are similar, but I can't seem to adapt the code to do what I want without getting a debug error.

You can spot a value using the MATCH method. After that, you can use that Rw to transfer data to another sheet:
Sub FindRowTransferData()
Dim Rw As Long, myVAL As String
myVAL = Application.InputBox("Enter search value:", "Search", "John Doe", Type:=2)
If myVAL = "False" Then Exit Sub
On Error Resume Next
Rw = Application.WorksheetFunction.Match(myVAL, Sheets("RAW_Data").Range("E:E"), 0)
On Error Goto 0
If Rw = 0 Then
MsgBox "The search value '" & myVAL & "' was not found"
Exit Sub
End If
'MsgBox "The search value '" & myVAL & "' was found on row: " & Rw
With Sheets("Formatted")
.Range("B3").Value = Sheets("RAW_Data").Range("A" & Rw).Value 'name
.Range("B4").Value = Sheets("RAW_Data").Range("B" & Rw).Value 'address
.Range("C3").Value = Sheets("RAW_Data").Range("C" & Rw).Value 'phone
'etc....
End With
End Sub
Based on the comments below, these suggested edits:
Rw = Application.WorksheetFunction.Match(myVAL, Sheets("RAW_Data").Range("F:F"), 0)
On Error Goto 0
If Rw = 0 Then
MsgBox "The search value '" & myVAL & "' was not found"
Exit Sub
End If
'MsgBox "The search value '" & myVAL & "' was found on row: " & Rw
Sheets("RAW_Data").Rows(Rw).Copy Sheets("Formatted").Range("A" & Rows.Count).End(xlUp).Offset(1)

Related

Search worksheet for three names

Instead of looking for a number greater than 6 and sending it to another sheet. I want to look up 3 names so I can search a contact list and have it pull their information from the sheet to the report sheet.
below is my old code:
Private Sub CommandButton1_Click()
Dim ws As Worksheet, myCounter
Dim erow, myValue As Long
For Each ws In Sheets
If ws.Range("C3").Value > 6 Then
myCounter = 1
ws.Select
ws.Range("c3").Select
myValue = ws.Range("C3").Value
Worksheets("Report").Select
erow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
ActiveSheet.Cells(erow, 1) = myValue
nextValue = MsgBox("Value found in " & ws.Name & Chr(10) & "Continue?", vbInformation + vbYesvbNo, ws.Name & " C3 = " & ws.Range("C3").Value)
Select Case nextValue
Case Is = vbYes
Case Is = vbNo
Exit Sub
End Select
End If
Next ws
If myCounter = 0 Then
MsgBox "None of the sheets contains a " & Chr(10) & "value greater than 6 in cell C3 ", vbInformation, "Not Found"
End If
End Sub
I think the third row should be String instead of Long.
The names I'm looking for are "David" "Andrea" & "Caroline", not sure if I write it three times or use a loop. Also I can't figure out how to search in the entire spreadsheet for these names.
The code below will look for the names "David", "Andrea" and "Caroline" in cell "C3" in all of the worksheets. For every match it will copy it to the first empty row in Column A in "Report" worksheet.
Note: There is no need to use Select and ActiveSheet, instead use fully qualifed Cells and Worksheets.
Code
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
nextValue = MsgBox("Value found in " & .Name & Chr(10) & "Continue?", vbInformation + vbYesNo, .Name & " C3 = " & .Range("C3").Value)
Select Case nextValue
Case Is = vbYes ' <-- if you are not doing anything here, you don't need it >> maybe you don't need the entire `Select Case` here
Case Is = vbNo
Exit Sub
End Select
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
Comment: It seems you are not doing anything in the case of Case Is = vbYes in the Select Case below:
nextValue = MsgBox("Value found in " & .Name & Chr(10) & "Continue?", vbInformation + vbYesNo, .Name & " C3 = " & .Range("C3").Value)
Select Case nextValue
Case Is = vbYes ' <-- if you are not doing anything here, you don't need it >> maybe you don't need the entire `Select Case` here
Case Is = vbNo
Exit Sub
End Select
You can replace the entire thing with :
If MsgBox("Value found in " & .Name & Chr(10) & "Continue?", vbInformation + vbYesNo, .Name & " C3 = " & .Range("C3").Value) = vbNo Then
Exit Sub
End If

Checking If A Sheet Exists In An External Closed Workbook

I want to test whether certain sheets in the current workbook exist in another closed workbook and return a message saying which sheet/s are causing errors.
I prefer not to open/close the workbook so I'm trying to change the formula in a random cell to link to the workbook of filepath (fp) to test whether the sheet exists.
I've tested this with a dummy sheet that I know doesn't exist in the other workbook and it works but when I have more than one sheet that causes errors I get an "Application-defined or object-defined error". On the second iteration I believe the way the error handling is written causes the crash but I don't exactly understand how that works.
The code I've got is:
Sub SheetTest(ByVal fp As String)
Dim i, errcount As Integer
Dim errshts As String
For i = 2 To Sheets.Count
On Error GoTo NoSheet
Sheets(1).Range("A50").Formula = "='" & fp & Sheets(i).Name & "'!A1"
GoTo NoError
NoSheet:
errshts = errshts & "'" & Sheets(i).Name & "', "
errcount = errcount + 1
NoError:
Next i
Sheets(1).Range("A50").ClearContents
If Not errshts = "" Then
If errcount = 1 Then
MsgBox "Sheet " & Left(errshts, Len(errshts) - 2) & " does not exist in the Output file. Please check the sheet name or select another Output file."
Else
MsgBox "Sheets " & Left(errshts, Len(errshts) - 2) & " do not exist in the Output file. Please check each sheet's name or select another Output file."
End If
End
End If
End Sub
Hopefully you guys can help me out here, thanks!
Here's a slightly different approach:
Sub Tester()
Dim s As Worksheet
For Each s In ThisWorkbook.Worksheets
Debug.Print s.Name, HasSheet("C:\Users\blah\Desktop\", "temp.xlsm", s.Name)
Next s
End Sub
Function HasSheet(fPath As String, fName As String, sheetName As String)
Dim f As String
f = "'" & fPath & "[" & fName & "]" & sheetName & "'!R1C1"
HasSheet = Not IsError(Application.ExecuteExcel4Macro(f))
End Function
Just an update for Tim's Function for error Handling:
VBA:
Function HasSheet(fPath As String, fName As String, sheetName As String)
On Error Resume Next
Dim f As String
f = "'" & fPath & "[" & fName & "]" & sheetName & "'!R1C1"
HasSheet = Not IsError(Application.ExecuteExcel4Macro(f))
If Err.Number <> 0 Then
HasSheet = False
End If
On Error GoTo 0
End Function
Sub Tester()
MsgBox (Not IsError(Application.ExecuteExcel4Macro("'C:\temp[temp.xlsm]Sheetxyz'!R1C1")))
End Sub

Excel Application Crash due to Macro

During launching my macro the Excel application is crashed. If I test the macro with an integer the program runs properly (partnumber = 123). If I check with a string the application is crashed. Thus, no error code is visible for me. I assume that there is a type mismatch (but I set Variant for partnumber)
Sub SbIsInCOPexport()
Dim lastRow As Long
Dim i As Long
Dim found As Boolean
Dim partnumber As Variant
i = 1
found = False
partnumber = ActiveCell.Value
Windows("COPexport.xlsx").Activate
lastRow = Sheets(1).Cells.SpecialCells(xlLastCell).Row
Do While i < lastRow + 1
If Cells(i, 6).Value = partnumber Then
found = True
Exit Do
End If
i = i + 1
Loop
If found = True Then
Cells(i, 6).Select
MsgBox ("Searched part number: " & Str(partnumber) & vbNewLine & "Found part number: " _
& ActiveCell.Value & vbNewLine & "Address: " & Cells(i, 6).Address & vbNewLine & vbNewLine & "Test Order: " & _
Cells(i, 2).Value)
Windows("COPexport.xlsx").Activate
Else
MsgBox "Part number is not found in the COP samples!"
Windows("COPexport.xlsx").Activate
End If
End Sub
What can be the root cause?
I don't see any obvious issues, but consider using the .Find method of range object, like so:
Sub SbIsInCOPexport()
Dim partnumber as Variant
Dim rng as Range
Windows("COPexport.xlsx").Activate
partnumber = ActiveCell.Value
Set rng = Columns(6).Find(partnumber) '## Search in column 6 for partnumber
If rng Is Nothing Then
MsgBox "Part number is not found in the COP samples!"
Windows("COPexport.xlsx").Activate
Else
With rng
MsgBox ("Searched part number: " & Str(partnumber) & vbNewLine & _
"Found part number: " & .Value & vbNewLine & _
"Address: " & .Address & vbNewLine & vbNewLine & _
"Test Order: " & .Offset(0,-4).Value) '## Get the value from column 2
End With
End If
End Sub

macro to check non blank cells in a column to ensure isdate()

I've been looking to write a macro to check 3 columns to ensure the contents are a date value. The columns can contain empty cells.
The below returns a message box for each cell that is not a date, even the blanks.
Sub DateCheck()
With ActiveSheet
lastRow = .Range("AB" & Rows.Count).End(xlUp).Row
For RowCount = 2 To lastRow
POC = .Range("AB" & RowCount)
If Not IsDate(POC) Then
MsgBox ("Please enter valid date in Cell : AB" & RowCount & ". Example: dd/mm/yyyy")
End If
Next RowCount
End With
End Sub
Could anybody be so kind as to help to adjust this to look at 3 non-adjacent columns, ignore blank cells and only return one message per column in the event it finds non-date values?
Thanks as always
Chris
Code:
Sub DateCheck()
Dim s(2) As String
Dim i As Integer
Dim o As String
Dim lastRow As Long
Dim r As Long
'Enter columns here:
s(0) = "A"
s(1) = "B"
s(2) = "C"
For i = 0 To 2
With ActiveSheet
lastRow = .Range(s(i) & Rows.Count).End(xlUp).Row
For r = 2 To lastRow
POC = .Range(s(i) & r)
If Not IsDate(POC) Then
o = o & ", " & .Range(s(i) & r).Address
End If
Next r
MsgBox ("Please enter valid date in Cells : " & Right(o, Len(o) - 1) & ". Example: dd/mm/yyyy")
o = ""
End With
Next i
End Sub
I would change your loop to a For Each In ... Next and use .Union to construct a range of non-adjacent columns.
Sub MultiDateCheck()
Dim lr As Long, cl As Range, rng As Range, mssg As String
With ActiveSheet
lr = .Range("AB" & Rows.Count).End(xlUp).Row
Set rng = Union(.Range("AB2:AB" & lr), .Range("AM2:AM" & lr), .Range("AZ2:AZ" & lr))
For Each cl In rng
If Not IsDate(cl.Value) And Not IsEmpty(cl) Then _
mssg = mssg & cl.Address(0, 0) & Space(4)
Next cl
End With
If CBool(Len(mssg)) Then
MsgBox ("Please enter valid date(s) in Cell(s): " & Chr(10) & Chr(10) & _
mssg & Chr(10) & Chr(10) & _
"Example: dd/mm/yyyy")
Else
MsgBox "All dates completed!"
End If
Set rng = Nothing
End Sub
I've used a single lastrow from column AB to determined the scope of the cells to be examined but individual rows for each column could easily be compensated for.
Addendum: Code modified for a single message showing rogue non-date/non-blank cells (as below). The Chr(10) is simply a line feed character.
                     

Save 2 different worksheets in the same workbook using coding

I use Excel to do an invoice system for my company. I've had to make it "dummy proof" for some of the other employees that use the program. I use several codes to make it successful. I have two sheets: Carolina Fireworks Order Form and Back Order. There is a macro on Carolina Fireworks Order Form that copies any cells over to the Back Order Form (this is an exact copy of Carolina Fireworks Order Form except that in the C7 where customer name is placed it automatically says Customer name and BO).
I have a code that automatically saves the file into a specific folder with C7 (customer name) and current date. Is there a way that I can add a code that if I hit the macro button to copy over the BO cells that it will automatically save Back Order sheet seperately with file name C7 and current date? Then when I hit the x buttom my other code will automatically save Carolina Fireworks Order Form (sheet 1)?
Does this make sense? I'm not a code writer so I had to search forever to get the code below to work. If there is a better way to do this then I'm completely open to it! Below is the current code that I am using for Module 1:
Sub myOpenCode()
'Standard module code, like: Module1.
Dim strCustomer$, strMsg$, myUpDate$, strCustNm$
Application.EnableEvents = True
On Error GoTo myErr
strCustomer = Sheets("Carolina Fireworks Order Form").Range("C7").Value
'Test for current customer!
If strCustomer <> "" Then
strMsg = "The current customer name is:" & vbLf & vbLf & _
strCustomer & vbLf & vbLf & _
"Change this customer name to a different Name?"
'Test for customer name update?
myUpDate = MsgBox(strMsg, vbQuestion + vbYesNo, "Add Customer?")
'Chose "Yes" button!
If myUpDate = 6 Then
'Change current customer's name!
strCustNm = InputBox(strMsg, "Change Customer Name!", "")
End If
'Chose "No" button!
If myUpDate = 7 Then
'Keep current customer name!
Application.EnableEvents = True
Exit Sub
End If
Else
'Get customer name!
strMsg = "The current customer name is:" & vbLf & vbLf & _
"""EMPTY!""" & vbLf & vbLf & _
"Add a customer name:"
'Force add customer name add!
myGetCustNm:
strCustNm = InputBox(strMsg, "Add Customer Name!", "")
If strCustNm = "" Then GoTo myGetCustNm
End If
'Load customer name!
Sheets("Carolina Fireworks Order Form").Range("C7").Value = strCustNm
Application.EnableEvents = True
Exit Sub
myErr:
'GoTo Error routine!
Call myErrHandler(Err)
End Sub
Sub myCloseCode()
'Standard module code, like: Module1.
Dim strDate$, strCustomer$, strFileNm$, strMsg$, myUpDate$
Application.EnableEvents = False
On Error GoTo myErr
'Test for Save option or Exit without saving?
strMsg = "Save this file before closing?"
myUpDate = MsgBox(strMsg, vbQuestion + vbYesNo, "Save Now?")
'Chose "Yes" button!
If myUpDate = 6 Then GoTo mySave
'Chose "No" button!
If myUpDate = 7 Then
Application.EnableEvents = True
Exit Sub
End If
mySave:
'Build file name!
strDate = DatePart("m", Date) & "-" & _
DatePart("d", Date) & "-" & _
Right(DatePart("yyyy", Date, vbUseSystemDayOfWeek, vbUseSystem), 4)
strCustomer = Sheets("Carolina Fireworks Order Form").Range("C7").Value
strFileNm = "\\Owner-hp\Users\Public\Customers\" & strCustomer & "-" & strDate & ".xlsm"
'Save current file!
ActiveWorkbook.SaveAs Filename:=strFileNm
Application.EnableEvents = True
ActiveWorkbook.Close
Exit Sub
myErr:
'GoTo Error routine!
Call myErrHandler(Err)
Application.EnableEvents = True
End Sub
Private Sub myErrHandler(myErr As ErrObject)
'Standard module code, like: Module1.
'Error Trap Routine!
Dim myMsg$
'Build Error Message!
myMsg = "Error Number : " & Str(myErr.Number) & vbLf & _
"Error Location: " & myErr.Source & vbLf & _
"Error Description: " & myErr.Description & vbLf & vbLf & _
"Context: " & myErr.HelpContext & vbLf & _
"Help File: " & myErr.HelpFile
'Show Error Message!
MsgBox myMsg & vbLf & vbLf & _
"Use the ""Help"" button for more information, on this ERROR!", _
vbCritical + vbMsgBoxHelpButton, _
Space(3) & "Error!", _
myErr.HelpFile, _
myErr.HelpContext
End Sub
Module 2:
Sub CopyBO()
'Copy cells of cols A,B,D from rows containing "BO" in
'col I of the active worksheet (source sheet) to cols
'A,B,D of Sheet2 (destination sheet)
Dim DestSheet As Worksheet
Set DestSheet = Worksheets("Back Order")
Dim sRow As Long 'row index on source worksheet
Dim dRow As Long 'row index on destination worksheet
Dim sCount As Long
sCount = 0
For sRow = 1 To 65536
'use pattern matching to find "BO" anywhere in cell
If Cells(sRow, "I") Like "*BO*" Then
sCount = sCount + 1
'copy cols A,B, D
Cells(sRow, "A").Copy Destination:=DestSheet.Cells(sRow, "A")
Cells(sRow, "B").Copy Destination:=DestSheet.Cells(sRow, "B")
End If
Next sRow
MsgBox sCount & " Back Ordered rows copied", vbInformation, "Transfer Done"
End Sub
Below code will create a copy of Back Order Sheet when procedure CopyBO is called.
Sub CopyBO()
'Copy cells of cols A,B,D from rows containing "BO" in
'col I of the active worksheet (source sheet) to cols
'A,B,D of Sheet2 (destination sheet)
Dim DestSheet As Worksheet
Set DestSheet = Worksheets("Back Order")
Dim n_Wkb As Workbook ' new workbook
Dim strFileNm As String
Dim sRow As Long 'row index on source worksheet
Dim dRow As Long 'row index on destination worksheet
Dim sCount As Long
sCount = 0
For sRow = 1 To 65536
'use pattern matching to find "BO" anywhere in cell
If Cells(sRow, "I") Like "*BO*" Then
sCount = sCount + 1
'copy cols A,B, D
Cells(sRow, "A").Copy Destination:=DestSheet.Cells(sRow, "A")
Cells(sRow, "B").Copy Destination:=DestSheet.Cells(sRow, "B")
End If
Next sRow
If sCount > 0 Then
DestSheet.Copy
Set n_Wkb = ActiveWorkbook
' Get the file path
strCustomer = ThisWorkbook.Sheets("Carolina Fireworks Order Form").Range("C7").Value
strFileNm = "\\Owner-hp\Users\Public\Customers\" & strCustomer
strFileNm = strFileNm & Format(Now(), "DD-MM-YY hh.mm.ss") & ".xlsx"
'save
n_Wkb.SaveAs strFileNm
n_Wkb.Close
End If
MsgBox sCount & " Back Ordered rows copied", vbInformation, "Transfer Done"
End Sub