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
Related
I am a beginner in Excel VBA but I would like to create a file where I can select certain worksheets by means of a userform with checkboxes. In principle, it is then intended that only the check boxes where the value is true should be exported.
Below I have 2 codes that work well separately from each other but I have not yet been able to get them to work together.
Note: both codes come from the internet.
If possible I would like to write a loop to keep the overview.
the code to export sheets as pdf and put them in a outlook
Sub Saveaspdfandsend1()
Dim xSht As Worksheet
Dim xFileDlg As FileDialog
Dim xFolder As String
Dim xYesorNo, I, xNum As Integer
Dim xOutlookObj As Object
Dim xEmailObj As Object
Dim xUsedRng As Range
Dim xArrShetts As Variant
Dim xPDFNameAddress As String
Dim xStr As String
xArrShetts = Array("test", "Sheet1", "Sheet2") 'Enter the sheet names you will send as pdf files enclosed with quotation marks and separate them with comma. Make sure there is no special characters such as \/:"*<>| in the file name.
For I = 0 To UBound(xArrShetts)
On Error Resume Next
Set xSht = Application.ActiveWorkbook.Worksheets(xArrShetts(I))
If xSht.Name <> xArrShetts(I) Then
MsgBox "Worksheet no found, exit operation:" & vbCrLf & vbCrLf & xArrShetts(I), vbInformation, "Kutools for Excel"
Exit Sub
End If
Next
Set xFileDlg = Application.FileDialog(msoFileDialogFolderPicker)
If xFileDlg.Show = True Then
xFolder = xFileDlg.SelectedItems(1)
Else
MsgBox "You must specify a folder to save the PDF into." & vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Must Specify Destination Folder"
Exit Sub
End If
'Check if file already exist
xYesorNo = MsgBox("If same name files exist in the destination folder, number suffix will be added to the file name automatically to distinguish the duplicates" & vbCrLf & vbCrLf & "Click Yes to continue, click No to cancel", _
vbYesNo + vbQuestion, "File Exists")
If xYesorNo <> vbYes Then Exit Sub
For I = 0 To UBound(xArrShetts)
Set xSht = Application.ActiveWorkbook.Worksheets(xArrShetts(I))
xStr = xFolder & "\" & xSht.Name & ".pdf"
xNum = 1
While Not (Dir(xStr, vbDirectory) = vbNullString)
xStr = xFolder & "\" & xSht.Name & "_" & xNum & ".pdf"
xNum = xNum + 1
Wend
Set xUsedRng = xSht.UsedRange
If Application.WorksheetFunction.CountA(xUsedRng.Cells) <> 0 Then
xSht.ExportAsFixedFormat Type:=xlTypePDF, Filename:=xStr, Quality:=xlQualityStandard
Else
End If
xArrShetts(I) = xStr
Next
'Create Outlook email
Set xOutlookObj = CreateObject("Outlook.Application")
Set xEmailObj = xOutlookObj.CreateItem(0)
With xEmailObj
.Display
.To = ""
.CC = ""
.Subject = "????"
For I = 0 To UBound(xArrShetts)
.Attachments.Add xArrShetts(I)
Next
If DisplayEmail = False Then
'.Send
End If
End With
End Sub
the other code i tried I can see which checkbox is checked unfortunately I can't rewrite it so only the checked boxes will be exported to pdf.
Private Sub CommandButton100_Click()
For i = 100 To 113
If UserForm2.Controls("CheckBox" & i).Value = True Then
a = a + 1
End If
Next i
k = 1
For i = 100 To 113
If UserForm2.Controls("CheckBox" & i).Value = True And a = 1 Then
b = UserForm2.Controls("CheckBox" & i).Caption & "."
ElseIf UserForm2.Controls("CheckBox" & i).Value = True And k <> a Then
b = b & UserForm2.Controls("CheckBox" & i).Caption & ", "
k = k + 1
ElseIf UserForm2.Controls("CheckBox" & i).Value = True And k = a Then
b = b & "and " & UserForm2.Controls("CheckBox" & i).Caption & "."
End If
Next i
MsgBox ("You have selected " & b)
End Sub
Can someone help me please I am struggling for some time now?
Please, try the next function:
Private Function sheetsArr(uF As UserForm) As Variant
Dim c As MSForms.Control, strCBX As String, arrSh
For Each c In uF.Controls
If TypeOf c Is MSForms.CheckBox Then
If c.value = True Then strCBX = strCBX & "," & c.Caption
End If
Next
sheetsArr = Split(Mid(strCBX, 2), ",") 'Mid(strCBX, 2) eliminates the first string character (",")
End Function
It will return an array composed from the ticked check boxes caption.
It can be used demonstratively, in this way:
Sub testSheetsArrFunction()
Debug.Print Join(sheetsArr(UserForm2), ",")
End Sub
The above code will return in Immediate Window a string containing the checked check boxes caption (separated by comma). It may be run from a standard module, too. Of course, the function must be copied in that module. And the form to be loaded, having some check boxes ticked.
Now, you have to change a single code line in your (working) code:
Replace:
xArrShetts = Array("test", "Sheet1", "Sheet2")
with:
xArrShetts = sheetsArr(UserForm2)
It should use the array built in the above function. Of course the function have to be copied in the module where to be called. If placed in the form code module, it can be simple called as:
xArrShetts = sheetsArr(Me)
Edited:
You should only paste the next code in the form code module and show the form:
Private Sub CommandButton1_Click()
Dim xSht As Worksheet
Dim xFileDlg As FileDialog
Dim xFolder As String
Dim xYesorNo, I, xNum As Integer
Dim xOutlookObj As Object
Dim xEmailObj As Object
Dim xUsedRng As Range
Dim xArrShetts As Variant
Dim xPDFNameAddress As String
Dim xStr As String
'xArrShetts = Array("test", "Sheet1", "Sheet2") 'Enter the sheet names you will send as pdf files enclosed with quotation marks and separate them with comma. Make sure there is no special characters such as \/:"*<>| in the file name.
xArrShetts = sheetsArr(Me)
For I = 0 To UBound(xArrShetts)
On Error Resume Next
Set xSht = Application.ActiveWorkbook.Worksheets(xArrShetts(I))
If xSht.Name <> xArrShetts(I) Then
MsgBox "Worksheet no found, exit operation:" & vbCrLf & vbCrLf & xArrShetts(I), vbInformation, "Kutools for Excel"
Exit Sub
End If
Next
Set xFileDlg = Application.FileDialog(msoFileDialogFolderPicker)
If xFileDlg.Show = True Then
xFolder = xFileDlg.SelectedItems(1)
Else
MsgBox "You must specify a folder to save the PDF into." & vbCrLf & vbCrLf & "Press OK to exit this macro.", vbCritical, "Must Specify Destination Folder"
Exit Sub
End If
'Check if file already exist
xYesorNo = MsgBox("If same name files exist in the destination folder, number suffix will be added to the file name automatically to distinguish the duplicates" & vbCrLf & vbCrLf & "Click Yes to continue, click No to cancel", _
vbYesNo + vbQuestion, "File Exists")
If xYesorNo <> vbYes Then Exit Sub
For I = 0 To UBound(xArrShetts)
Set xSht = Application.ActiveWorkbook.Worksheets(xArrShetts(I))
xStr = xFolder & "\" & xSht.Name & ".pdf"
xNum = 1
While Not (Dir(xStr, vbDirectory) = vbNullString)
xStr = xFolder & "\" & xSht.Name & "_" & xNum & ".pdf"
xNum = xNum + 1
Wend
Set xUsedRng = xSht.UsedRange
If Application.WorksheetFunction.CountA(xUsedRng.Cells) <> 0 Then
xSht.ExportAsFixedFormat Type:=xlTypePDF, Filename:=xStr, Quality:=xlQualityStandard
End If
xArrShetts(I) = xStr
Next
'Create Outlook email
Set xOutlookObj = CreateObject("Outlook.Application")
Set xEmailObj = xOutlookObj.CreateItem(0)
With xEmailObj
.Display
.To = ""
.CC = ""
.Subject = "????"
For I = 0 To UBound(xArrShetts)
.Attachments.Add xArrShetts(I)
Next
If DisplayEmail = False Then
'.Send
End If
End With
End Sub
Private Function sheetsArr(uF As UserForm) As Variant
Dim c As MSForms.Control, strCBX As String, arrSh
For Each c In uF.Controls
If TypeOf c Is MSForms.CheckBox Then
If c.Value = True Then strCBX = strCBX & "," & c.Caption
End If
Next
sheetsArr = Split(Mid(strCBX, 2), ",") 'Mid(strCBX, 2) eliminates the first string character (",")
End Function
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
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
Hello there fellow StackOverflow users,
So my issue is with a workbook that heavily uses VBA to automate and calculate several functions. However the one in particular is a function I wrote that updates the code and named ranges of the workbook when the master copy is updated, which is done simply by a version number in a cell check.
Function updateCheck(cVer As Double) As Double
Dim currWB As Workbook, isWB As Workbook, iSht As Worksheet, ver As Range, wbName As String, path As String
Dim isCode As CodeModule, wbCode As CodeModule, wbMod As CodeModule, isMod As CodeModule, isNames As New Collection, isVal As New Collection
Dim tmp As Name, nm As Name, ws As Worksheet, tn As Range, verNum As Double, nStr As String, raf As Boolean, tStr As String
path = "Q:\JWILDE\": wbName = "testsheet.xlsm"
Set currWB = ThisWorkbook
With currWB
.Activate
Set wbCode = .VBProject.VBComponents("ThisWorkbook").CodeModule
Set iSht = .Sheets(1)
End With
If Dir(path & wbName) <> "" And Not currWB.path & "\" Like path Then
Set isWB = Workbooks.Open(path & wbName, ReadOnly:=True)
isWB.Activate
verNum = isWB.Names("VerNum").RefersToRange
Else
updateCheck = cVer
Exit Function
End If
If cVer < verNum Then
Debug.Print "...update required, current version: " & verNum
With isWB
With .VBProject
Set isMod = .VBComponents("ISCode").CodeModule
Set isCode = .VBComponents("ThisWorkbook").CodeModule
End With
'--- COMPILES LIST OF NAMES FROM STANDARD SHEET ---
For Each nm In .Names
nVal = "=SHT!"
key = getNRVal(nm.Name, 3)
nStr = getNRVal(nm.RefersToLocal, 3)
Debug.Print "Sheet set to: " & getNRVal(nm.Name, 1)
.Sheets(getNRVal(nm.Name, 1)).Unprotect Password:="jwedit"
Set tn = .Sheets(getNRVal(nm.Name, 1)).Range(nStr) 'Untested...
On Error Resume Next
tStr = isNames(key)
If tStr <> "" Then
tStr = ""
Else
If nm.Parent.Name = .Name Then
Set tn = .Sheets(1).Range(nStr)
nVal = "=WB!"
isVal.Add tn, key
Debug.Print "isVal > " & isVal(key).Name
End If
isNames.Add key & nVal & nStr, key
Debug.Print "...added: " & isNames.Item(key)
End If
Next nm
End With
If isCode.CountOfLines > 0 And isMod.CountOfLines > 0 Then
With currWB.VBProject
Set wbCode = .VBComponents("ISCode").CodeModule
wbCode.DeleteLines 1, wbCode.CountOfLines
wbCode.AddFromString isMod.Lines(1, isMod.CountOfLines)
Set wbCode = .VBComponents("ThisWorkBook").CodeModule
wbCode.DeleteLines 1, wbCode.CountOfLines
wbCode.AddFromString isCode.Lines(1, isCode.CountOfLines)
updateCheck = verNum
End With
Else
Debug.Print "Error. Unable to get updated code."
updateCheck = cVer
End If
isWB.Close SaveChanges:=False
currWB.Activate
On Error Resume Next
Dim wbStr As String: wbStr = isWB.Name
If wbStr <> "" Then
Debug.Print "WARNING: " & wbStr & " is still open!"
Else: Debug.Print "Successfully closed isWB."
End If
'--- CHECKS THROUGH EACH SHEET FROM CURRENT WB ---
For Each ws In currWB.Worksheets
ws.Unprotect Password:="jwedit"
'--- CHECK TO REMOVE INVALID OR INCORRECT NAMES ---
For Each nm In ws.Names
raf = False
key = getNRVal(nm.Name, 3) '--> SHEET!NAME > NAME
nStr = getNRVal(nm.RefersTo, 3) '---> SHEET!REF > REF
tStr = isNames(key) 'Could change this to: getNRVal(isNames(key),3) to return just REF or nothing.
Debug.Print "...[" & key & "]..."
If tStr <> "" Then 'MATCH FOUND...
Set tn = ws.Range(getNRVal(tStr, 3)) 'Should be the CORRECT RefTo from isNames.
'--- NAME ON WRONG SHEET ---
If ws.Index > 1 And getNRVal(tStr, 2) Like "WB" Then
Debug.Print " > REMOVE: [" & key & "] does not belong on " & ws.Name
nm.Delete
'--- NAME CORRECT BUT REFTO ISNT ---
ElseIf Not nStr Like getNRVal(tStr, 3) Then
Debug.Print " > INCORRECT: REF (" & nStr & ") of [" & key & "] should be (" & tn.Address & ")."
nm.RefersTo = tn
End If
tStr = ""
Else '--- NO MATCH FOUND / INVALID NAME ---
Debug.Print " > REMOVE: [" & key & "] is invalid."
raf = True
End If
If raf = True Then
Set tn = ws.Range(nStr)
tn.ClearContents
nm.Delete
End If
Next nm
'--- CHECKING FOR NAMES TO ADD ---
For n = 1 To isNames.Count
raf = False
key = getNRVal(isNames(n), 1) '--> NAME
nStr = getNRVal(isNames(n), 3) '--> REF
nVal = getNRVal(isNames(n), 2) '--> SHT/WB
Debug.Print "Looking for [" & key & "] on " & ws.Name
If ws.Index = 1 And nVal Like "WB" Then
tStr = currWB.Names(key, RefersTo:=nStr)
If tStr <> "" Then
tStr = ""
Else: raf = True
End If
ElseIf ws.Index > 1 And nVal Like "SHT" Then
tStr = ws.Names(key, RefersTo:=nStr)
If tStr <> "" Then
tStr = ""
Else: raf = True
End If
End If
If raf = True Then
Set tn = ws.Range(nStr)
ws.Names.Add key, tn
tStr = isVal(key).Name
If tStr <> "" Then
ws.Names.Add key, tn
tn.Value = isVal(key).Value
End If
Debug.Print " > ADDED: [" & ws.Names(key).Name & "] with REF [" & ws.Names(key).RefersToLocal & "] on " & ws.Name
End If
Next n
ws.Protect Password:="jwedit", UserInterfaceOnly:=True, AllowFormattingCells:=False
Next ws
Debug.Print " --- DONE CHECKING NAMES --- "
iSht.Activate
updateCheck = verNum
isWB.Close SaveChanges:=False
Else
Debug.Print "No update needed."
updateCheck = verNum
End If
End Function
Did my best to make it all readable, and sorry if its a bit messy. I think I have narrowed down the problem to do with protecting/unprotecting the sheets within the For Each ws in currWB.Worksheets loop as when even when I comment out the other loops for adding/removing names it still causes an Automation Error and then Excel crashes. I should also mention that every sheet only has a select cells that are editable/unprotected to try and avoid unwanted editing and format changing, which is why I need to unprotect before adding/removing names or changing cell values it seems.
Any help on this would be appreciated, or even comments if you feel I could do this any better.
Thank you!
I remember having this error and it was to do with how I was protecting the sheet for a finish I used -
For Each ws In ActiveWorkbook.Worksheets
If ws.ProtectContents = True Then
ws.Unprotect "password"
End If
Next ws
and this
For Each ws In ActiveWorkbook.Worksheets
ws.Protect "password", DrawingObjects:=True, Contents:=True, _
AllowSorting:=True, AllowFiltering:=True
Next ws
to protect
OK - I think...problem solved or found or both. Although the answer above did help thank you.
Seems the problem was down to possibly having code in the worksheet_activate and worksheet_change function, which may well have caused some continuous loop when iterating through the sheets. This was resolved simply by using Application.EnableEvents = False before the Function above is called as I don't intend any other functions/subs to be run when looping through sheets like this.
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