Search worksheet for three names - vba

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

Related

VBA loop through rows, select a couple of them & then delete them

I have a dataset, in which i want to delete every x row of it (x = userinput).
If i delete the rows immediately, the endresult will be incorrect because the row order changes with every deletion.
I wrote this code so far:
Sub Delete_Data()
'Take userinput
Dim userInput As Variant
Dim i As Long
Do While True
userInput = InputBox("please enter a number between 2-100", _
"Lets delete some data XD")
If IsNumeric(userInput) And userInput >= 2 _
And userInput <= 100 Then
Exit Do
End If
If MsgBox("Invalid Input, please redo or cancel", _
vbOKCancel, "Invalid input") = vbCancel Then Exit Do
Loop
'Delete Rows
Worksheets("Sheet1").Activate
For i = 2 To Rows.count Step userInput
If Rows.Cells(i, 1).Value = "" Then
Rows(ActiveCell.Row).EntireRow.Delete
MsgBox "you have successfully deleted every " _
& userInput & "th row!"
Exit For
Else
Rows(i).EntireRow.Select
End If
Next i
End Sub
The problem is that, the previous selection of a row disappears as soon as a new row gets selected. I hope you guys can help me out.
Using a union your code would look like this:
Sub Delete_Data()
'Take userinput
Dim userInput As Variant
Dim i As Long
Do While True
userInput = InputBox("please enter a number between 2-100", _
"Lets delete some data XD")
If IsNumeric(userInput) And userInput >= 2 _
And userInput <= 100 Then
Exit Do
End If
If MsgBox("Invalid Input, please redo or cancel", _
vbOKCancel, "Invalid input") = vbCancel Then Exit Do
Loop
'Delete Rows
With Worksheets("Sheet1")
Dim delrng As Range
For i = 2 To .Cells(.Rows.Count, 2).End(xlUp).Row Step userInput 'Change 2 to whatever column has the most data
If .Cells(i, 1).Value = "" Then
If delrng Is Nothing Then
Set delrng = .Cells(i, 1).EntireRow
Else
Set delrng = Union(delrng, .Cells(i, 1).EntireRow)
End If
End If
Next i
End With
delrng.Delete
Select Case True
Case Right(userInput, 1) = 1 And Not userInput = 11
MsgBox "you have successfully deleted every " _
& userInput & "st row!"
Case Right(userInput, 1) = 2 And Not userInput = 12
MsgBox "you have successfully deleted every " _
& userInput & "nd row!"
Case Right(userInput, 1) = 3 And Not userInput = 13
MsgBox "you have successfully deleted every " _
& userInput & "rd row!"
Case Else
MsgBox "you have successfully deleted every " _
& userInput & "th row!"
End Select
End Sub
I expanded your Msgbox to properly concatenate based on the number.
Thanks for your inputs:
thats the final code
Option Explicit
Sub Delete_Data()
'Take userinput
Dim userInput As Variant
Dim i As Long
Do While True
userInput = InputBox("please enter a number between 2-100", _
"Lets delete some data XD")
If IsNumeric(userInput) And userInput >= 2 _
And userInput <= 100 Then
Exit Do
End If
If MsgBox("Invalid Input, please redo or cancel", _
vbOKCancel, "Invalid input") = vbCancel Then Exit Sub
Loop
'Activate rows "to be deleted"
With Worksheets("Sheet1")
Dim delRange As Range
For i = 2 To .Cells(.Rows.count, 2).End(xlUp).Row Step userInput
If .Cells(i, 1).Value = "" Then
Exit For
ElseIf delRange Is Nothing Then
Set delRange = .Cells(i, 1).EntireRow
Else
Set delRange = Union(delRange, .Cells(i, 1).EntireRow)
End If
Next i
End With
'Mark rows "to be deleted"
delRange.Interior.ColorIndex = 6
'Ask for deltetion cofirmation
Dim answer As Variant
answer = MsgBox("Do you really want to delete the selected rows?", _
vbQuestion + vbYesNo + vbDefaultButton2, "Confirm deletion")
If answer = vbYes Then
delRange.Delete
Else
delRange.Interior.ColorIndex = xlNone
Exit Sub
End If
'Give feedback to user & look for correct english wording
Select Case True
Case Right(userInput, 1) = 1 And Not userInput = 11
MsgBox "you have successfully deleted every " _
& userInput & "st row!"
Case Right(userInput, 1) = 2 And Not userInput = 12
MsgBox "you have successfully deleted every " _
& userInput & "nd row!"
Case Right(userInput, 1) = 3 And Not userInput = 13
MsgBox "you have successfully deleted every " _
& userInput & "rd row!"
Case Else
MsgBox "you have successfully deleted every " _
& userInput & "th row!"
End Select
End Sub

vba locking / unlocking selection macro

I want to create a macro to lock / unlock cells based on Locked range property, but I am having trouble firing the Case Null section of the statement( The first 2 work fine)
Sub Lockunlockselection()
Dim c As Range
Dim wb As Workbook
Dim ws As Worksheet
'Dim lck As String
'Dim unlck As String
Set wb = ActiveWorkbook
Set ws = wb.ActiveSheet
'lck = Empty
'unlck = Empty
Set c = selection
Select Case c.Locked
Case False
c.Locked = True
msgbox "Selection " & c.Address & " is now locked!", vbInformation, Date
Case True
c.Locked = False
msgbox "Selection " & c.Address & " is now unlocked!", vbInformation, Date
Case Null ' this would be if mix of locked and unlocked
c.Locked = True
msgbox "Mix of locked and unlocked cells!" & vbLf & vbLf & "Cells are all now locked!", vbInformation + vbExclamation, "Info.."
End Select
End Sub
Why is this not firing??
thanks!
Solution (if anyone is interested):
Sub Lockunlockselection()
Dim c As Range
Dim wb As Workbook
Dim ws As Worksheet
'Dim lck As String
'Dim unlck As String
Set wb = ActiveWorkbook
Set ws = wb.ActiveSheet
'lck = Empty
'unlck = Empty
Set c = selection
If IsNull(c.Locked) = True Then ' this would be if mix of locked and unlocked
msgbox "Mix of locked and unlocked cells!" & vbLf & vbLf & "Cells are all now locked!", vbExclamation + vbMsgBoxSetForeground, "Info.."
c.Locked = True
Else
Select Case c.Locked
Case False
c.Locked = True
msgbox "Selection " & c.Address & " is now locked!", vbInformation, Date
Case True
c.Locked = False
msgbox "Selection " & c.Address & " is now unlocked!", vbInformation, Date
End Select
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

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

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)