In Excel VBA, I am running into an "error" that halts the macro and a message displays "Code execution has been interrupted." I wrote error in quotations because when I selected debug and examined the line of code that prompted the error, I saw that it was logically sound.
I originally ran into the error at On Error GoTo 0. When I comment out a block around the error, then I get a new line that produces the same error. And, again, when I examine it in debug mode the new "error" is logically sound. Here is the exact line:
If rRange.Row <> 3 And rRange.Row <> 17 Then
FYI, rRange.Row = 3 in this case, so it shouldn't produce an error.
Why is this happening and how can I fix it?
UPDATE Code now produces the error on the End Sub line.
Here is the section that fails:
Sub Review()
Dim WorkRange As Range
Dim FoundCells As Range
Dim Cell As Range
Dim a As String
Dim policy As String
Dim rRange As Range
Set RR = Sheets("Ready for Review")
Set OG = ActiveSheet
OG.Unprotect ("Password")
RR.Activate
On Error Resume Next
Application.DisplayAlerts = False
Set rRange = Application.InputBox(Prompt:= _
"Please select POLICY to review.", _
Title:="SPECIFY POLICY", Type:=8)
On Error GoTo 0
Application.DisplayAlerts = True
If rRange.Row <> 3 And rRange.Row <> 17 Then
MsgBox "Value other than a POLICY was selected. Select the cell that contains the correct policy number."
Exit Sub
Else
policy = rRange.Value
End If
Application.ScreenUpdating = False
OG.Cells(12, 2).Locked = False
Set WorkRange = OG.UsedRange
For Each Cell In WorkRange
If Cell.Locked = False Then
col1 = Cell.Column
Row = Cell.Row
a = OG.Cells(Row, 1)
If Not a = "" Then
row2 = Application.WorksheetFunction.Match(a, RR.Range("A:A"), 0)
Cell.Value = RR.Cells(row2, rRange.Column + col1 - 2)
End If
End If
Next Cell
OG.Unprotect ("Password")
OG.Cells(33, 3).Locked = False
If (Right(OG.Cells(5, 2), 2) = "UL" Or Right(OG.Cells(5, 2), 2) = "IL" Or Right(OG.Cells(5, 2), 2) = "PL") Then
With OG.Cells(33, 3)
.Value = "=IF(INDEX(B:B,MATCH(""Total*"",A:A,0))="""",0,INDEX(B:B,MATCH(""Total*"",A:A,0)))-SUM(C34:C37)"
.Locked = True
End With
ElseIf Right(OG.Cells(5, 2), 2) = "WL" Then
With OG.Cells(33, 3)
.Value = "=IF(INDEX(B:B,MATCH(""Total*"",A:A,0))="""",0,INDEX(B:B,MATCH(""*"",A:A,0))) - IFERROR(INDEX(C34:C37,MATCH(""Additional"",B34:B37, 0)),0) - IFERROR(INDEX(C34:C37,MATCH(""Paid"",B34:B37,0)),0) - IFERROR(INDEX(C34:C37,MATCH(""Additional Agreement - SPPUA"",B34:B37, 0)),0) - IFERROR(INDEX(C34:C37,MATCH(""Flexible Agreement - FLXT10/20"",B34:B37, 0)),0)"
.Locked = True
End With
Else
With OG.Cells(33, 3)
.Value = "=IF(INDEX(B:B,MATCH(""Total*"",A:A,0))="""",0,INDEX(B:B,MATCH(""*"",A:A,0)))"
.Locked = True
End With
End If
OG.Activate
Cells(Application.WorksheetFunction.Match("Last Month Paid ($)", Range("A:A"), 0), 2).NumberFormat = "$#,##0.00;[Red]$#,##0.00"
OG.Protect ("Password")
Application.ScreenUpdating = True
End Sub
Oh, that brings back memories for me. I think I used to get this error about 10 years ago Excel 2003? Maybe?. Excel would get itself into a bit of a state. Nothing was wrong with the code, just it would keep coming back with that error.
If you save your work close Excel and then reopen, does the error go away?
If I remember right, it was caused when I called some external API. Maybe some other API call in your is causing this error but manifesting at this point... perhaps.
Sorry but it was 10+ years ago :)
even if you went through it, you may want to consider the following "restyling" of the code you posted
Option Explicit
Sub Review()
Dim Cell As Range, rRange As Range
Dim a As String
Dim RR As Worksheet, OG As Worksheet
Set RR = Sheets("Ready for Review")
Set OG = ActiveSheet
OG.Unprotect ("Password")
Set rRange = GetUserInpt(RR)
If rRange Is Nothing Then
MsgBox "You aborted the POLICY selection" _
& vbCrLf & vbCrLf _
& "the procedure ends" _
, vbInformation
Exit Sub
End If
Application.ScreenUpdating = False
OG.Cells(12, 2).Locked = False
For Each Cell In OG.UsedRange
With Cell
If Not .Locked Then
a = OG.Cells(.row, 1)
If Not a = "" Then .value = RR.Cells(CLng(Application.WorksheetFunction.Match(a, RR.Range("A:A"), 0)), _
rRange.Column + .Column - 2)
End If
End With
Next Cell
With OG.Cells(33, 3)
.Locked = False
Select Case Right(OG.Cells(5, 2), 2)
Case "UL", "IL", "PL"
.Formula = "=IF(INDEX(B:B,MATCH(""Total*"",A:A,0))="""",0,INDEX(B:B,MATCH(""Total*"",A:A,0)))-SUM(C34:C37)"
Case "WL"
.Formula = "=IF(INDEX(B:B,MATCH(""Total*"",A:A,0))="""",0,INDEX(B:B,MATCH(""*"",A:A,0))) - IFERROR(INDEX(C34:C37,MATCH(""Additional"",B34:B37, 0)),0) - IFERROR(INDEX(C34:C37,MATCH(""Paid"",B34:B37,0)),0) - IFERROR(INDEX(C34:C37,MATCH(""Additional Agreement - SPPUA"",B34:B37, 0)),0) - IFERROR(INDEX(C34:C37,MATCH(""Flexible Agreement - FLXT10/20"",B34:B37, 0)),0)"
Case Else
.value = "=IF(INDEX(B:B,MATCH(""Total*"",A:A,0))="""",0,INDEX(B:B,MATCH(""*"",A:A,0)))"
End Select
.Locked = True
End With
OG.Activate
Cells(Application.WorksheetFunction.Match("Last Month Paid ($)", Range("A:A"), 0), 2).NumberFormat = "$#,##0.00;[Red]$#,##0.00"
OG.Protect ("Password")
Application.ScreenUpdating = True
End Sub
Function GetUserInpt(sht As Worksheet) As Range
Dim rRange As Range
Application.DisplayAlerts = False
sht.Activate
On Error GoTo InputBoxCanceled
Do While rRange Is Nothing
Set rRange = Application.InputBox(Prompt:="Please select POLICY to review.", _
Title:="SPECIFY POLICY", _
Default:=sht.Cells(3, 1).Address, _
Type:=8)
If rRange.Parent.Name <> sht.Name Then
MsgBox "You must select a cell in '" & sht.Name & "' sheet"
sht.Activate
Set rRange = Nothing
Else
If rRange.row <> 3 And rRange.row <> 17 Then
MsgBox "Value other than a POLICY was selected" _
& vbCrLf & vbCrLf _
& "Select the cell that contains the correct policy number" _
, vbCritical
Set rRange = Nothing
End If
End If
Loop
Set GetUserInpt = rRange
InputBoxCanceled:
On Error GoTo 0
Application.DisplayAlerts = True
End Function
the main revision applies to:
added a GetUserInpt function to handle the policy selection
this function:
checks for both the correct selection row and sheet, too (since it's possible the user shifts to another worksheet during selection!)
runs a loop until the user selects a proper cell
exits selection upon user canceling the InputBox, as the only loop escape possibility
made some simplifications here and there, like:
eliminated Activate statements unless really needed
reduced the amount of variables to only (nearly) strictly needed ones
added some With ... End With blocks to add readability
used a Select Case block instead of an If ... Then ... Else if ... Else ... End if one, for readability again
changed .Value to .Formula, for a proper syntax
all what above could help you with this project and in future ones, too
Related
I have created a UserForm with some textboxes and comboboxes inside, the data that is typed in textboxes are supposed to be inserted in cell in the sheet, the determation of which cell is based on the value in ComboBox4. unfortunately the code keeps giving me error: "Run-time error '13': Type mismatch" and I have not been able to find out what is going wrong?
if someone knows what the problem is please let me know.
Private Sub UserForm_Initialize()
ComboBox3.List = [ADMIN!e2:E1000].Value
ComboBox4.List = [PRODUCTION!O6:O1000].Value
End Sub
Private Sub ACCEPTBUTTON_Click()
Application.ScreenUpdating = False
Worksheets("PRODUCTION").Activate
Dim C As Long
For C = 1000 To 1 Step -1
If Cells(C + 1, 1) Like ComboBox4 Then
Cells(C + 1, 1).EntireRow.Select
Selection.EntireRow.Hidden = False
Application.CutCopyMode = False
End If
Next C
Range("AC" & (ActiveCell.Row)).Value = TextBox1.Value
Range("AD" & (ActiveCell.Row)).Value = TextBox2.Value
Range("AE" & (ActiveCell.Row)).Value = TextBox3.Value
Range("AF" & (ActiveCell.Row)).Value = TextBox4.Value
Range("AG" & (ActiveCell.Row)).Value = TextBox5.Value
Range("AH" & (ActiveCell.Row)).Value = TextBox6.Value
Range("AI" & (ActiveCell.Row)).Value = TextBox7.Value
Range("AJ" & (ActiveCell.Row)).Value = TextBox8.Value
ActiveCell.EntireRow.RowHeight = 16
Unload Me
Application.ScreenUpdating = True
End Sub
Here's some commented code that should work for you. I did find it strange that you populate the values in ComboBox4 from column O, but then search column A for matches, is that intentional? (In the provided code, it searches for matches from the same list as populated the combobox which will guarantee a match is found).
Also, instead of a 1000 long loop to find the matches, this uses a Range.Find loop to increase speed and efficiency.
'Declare userform variables that any of this userform's Subs can reference
Private wb As Workbook
Private wsAdm As Worksheet
Private wsPrd As Worksheet
Private rAdmList As Range
Private rPrdList As Range
Private Sub UserForm_Initialize()
'Populate userform variables
Set wb = ThisWorkbook
Set wsAdm = wb.Worksheets("ADMIN")
Set wsPrd = wb.Worksheets("PRODUCTION")
Set rAdmList = wsAdm.Range("E2", wsAdm.Cells(wsAdm.Rows.Count, "E").End(xlUp)) 'Dynamically size list
Set rPrdList = wsPrd.Range("O6", wsPrd.Cells(wsPrd.Rows.Count, "O").End(xlUp)) 'Dynamically size list
Me.ComboBox3.List = rAdmList.Value
Me.ComboBox4.List = rPrdList.Value
End Sub
Private Sub ACCEPTBUTTON_Click()
'Check if anything is selected from ComboBox4
If Me.ComboBox4.ListIndex = -1 Then
Me.ComboBox4.SetFocus
MsgBox "Must select a Production item"
Exit Sub
End If
'An item from the production list in combobox4 has been confirmed to be selected
'Search the corresonding ComboBox4 list range to find the corresponding row
'(In your original code, you are searching column A instead of the column that populated the combobox which is column O, is there a reason for that?)
Dim rFound As Range, sFirst As String
Set rFound = rPrdList.Find(Me.ComboBox4.Text, rPrdList(rPrdList.Cells.Count), xlValues, xlWhole)
If Not rFound Is Nothing Then
sFirst = rFound.Address 'Record first address of found item
Do
'Matching row found, unhide and populate cells with textbox values
'Note that there is currently no check or validation that the textboxes are populated
rFound.EntireRow.Hidden = False
wsPrd.Cells(rFound.Row, "AC").Value = Me.TextBox1.Text
wsPrd.Cells(rFound.Row, "AD").Value = Me.TextBox2.Text
wsPrd.Cells(rFound.Row, "AE").Value = Me.TextBox3.Text
wsPrd.Cells(rFound.Row, "AF").Value = Me.TextBox4.Text
wsPrd.Cells(rFound.Row, "AG").Value = Me.TextBox5.Text
wsPrd.Cells(rFound.Row, "AH").Value = Me.TextBox6.Text
wsPrd.Cells(rFound.Row, "AI").Value = Me.TextBox7.Text
wsPrd.Cells(rFound.Row, "AJ").Value = Me.TextBox8.Text
'Search for next cell that matches
Set rFound = rPrdList.FindNext(rFound)
Loop While rFound.Address <> sFirst 'Loop until back at first address
Else
'If the item wasn't found, it's because the user manually typed in something in the combobox, or other error occurred
Me.ComboBox4.SetFocus
MsgBox "Invalid value entered for Production item"
Exit Sub
End If
Unload Me
End Sub
I wrote this code over the weekend and it was blazing fast, when I got to work on Monday I sent an email before testing the code while servers had a load and it is infinitely slower. We are talking from 30 seconds to 15 minutes.
For x = 3 To SRLastRow
If Left(shMacro.Range("D" & x), 3) = "625" Then
shMacro.Range("BW" & x) = WorksheetFunction.XLookup(Arg1:=shMacro.Range("A" & x), Arg2:=WIPFile.Worksheets("Customer Master").Range("B:B"), Arg3:=WIPFile.Worksheets("Customer Master").Range("AD:AD"))
Else
shMacro.Range("BW" & x) = WorksheetFunction.XLookup(Arg1:=shMacro.Range("A" & x), Arg2:=WIPFile.Worksheets("Customer Master").Range("B:B"), Arg3:=WIPFile.Worksheets("Customer Master").Range("AH:AH"))
End If
If shMacro.Range("BW" & x) <> shMacro.Range("BX" & x) Then
shMacro.Range("BX" & x).Interior.ColorIndex = 3
ErrorCount = ErrorCount + 1
End If
Next x
I essentially need to pull in a value, then compare that pulled in value with a value on my Macro worksheet. If the values match do nothing, otherwise color the cell red.
I came up with the following, but haven't tested it fully yet, but the problem remains having to cycle through to find mismatches to color them.
shMacro.Range("BW3").Formula = "=IF(LEFT(D3,3)=""625"",XLOOKUP(TEXT(A3,""000""),'[WORKBOOK]Customer Master'!$AD:$AD),XLOOKUP(TEXT(A3,""000""),'[WORKBOOK]Customer Master'!$B:$B,'[WORKBOOK]Customer Master'!$AH:$AH))"
Range("BW3").AutoFill Destination:=Range("BW3:BW" & SRLastRow)
I've also tried looking into Arrays but I can't seem to figure those out. I think the autofill would be the fastest way to pull in the data, then somehow assign the two arrays (which would be columns BW and BX) and if they match do nothing, wherever they are different color BX + row reference red, and count the number of times it colored something red.
Should be a little faster (reducing cell reads without going "full array mode" and coloring all mismatches in one shot)
Sub Tester()
Dim x As Long, SRLastRow As Long
Dim colReturn As String, v, rngRed As Range, rw As Range
'...
'...
'...
Application.ScreenUpdating = False
For x = 3 To SRLastRow
Set rw = shMacro.Rows(x)
colReturn = IIf(Left(rw.Columns("D").Value, 3) = "625", "AD:AD", "AH:AH")
v = Application.XLookup( _
Arg1:=rw.Columns("A").Value, _
Arg2:=WIPFile.Worksheets("Customer Master").Range("B:B"), _
Arg3:=WIPFile.Worksheets("Customer Master").Range(colReturn))
If Not IsError(v) Then
rw.Columns("BW").Value = v
With rw.Columns("BX")
If v <> .Value Then
BuildRange rngRed, .Cells(1)
ErrorCount = ErrorCount + 1
End If
End With
End If
Next x
'color the mismatches if any
If Not rngRed Is Nothing Then rngRed.Interior.ColorIndex = 3
End Sub
'utility - build a range using Union
Sub BuildRange(ByRef rngTot As Range, rngAdd As Range)
If rngTot Is Nothing Then
Set rngTot = rngAdd
Else
Set rngTot = Application.Union(rngTot, rngAdd)
End If
End Sub
I think the reason for the slow processing is in the location of the WIPFile workbook. Therefore my code below minimizes the need to access it. I couldn't test my code for lack of data but I hope you will try it.
Sub Snippet()
' 214
Dim LookUpRng As Range ' in "Customer Master"
Dim ReturnVals As Variant ' values from "Customer Master"
Dim C As Long ' Lookup column in ReturnRng
Dim Fnd As Range ' search result
Dim x As Long ' loop counter: rows (why "x" and not "R" ?)
Dim ErrorCount As Variant
Dim Spike As String ' collect failed lookups
ErrorCount = 0
With WIPFile.Worksheets("Customer Master")
Set LookUpRng = .Columns("BB")
ReturnVals = .Range(.Columns("AD"), .Columns("AH")).Value
End With
With shMacro
For x = 3 To .Cells(.Rows.Count, "A").End(xlUp).Row
Set Fnd = LookUpRng.Find(.Cells(x, "A").Value, LookIn:=xlValues, LookAt:=xlWhole)
If Fnd Is Nothing Then
If Len(Spike) Then Spike = Spike & vbCr
Spike = Spike & String(6, " ") & """" & .Cells(x, 1).Value & """ in row " & x
Else
C = IIf(Left(.Cells(x, "D").Value, 3) = "625", 1, 5)
With .Cells(x, "BW")
.Value = ReturnVals(Fnd.Row, C)
If .Value <> .Cells(x, "BX").Value Then
.Interior.ColorIndex = 3
ErrorCount = ErrorCount + 1
End If
End With
End If
Next x
End With
If Len(Spike) Then
Spike = "The following look-ups were not successful." & vbCr & _
Spike & IIf(ErrorCount, vbCr, "")
Else
Spike = "All look-ups were successful."
End If
If ErrorCount = 0 Then ErrorCount = "No"
Spike = Spike & vbCr & ErrorCount & " matching error" & _
IIf(ErrorCount = 1, "", "s") & " were highlighted."
MsgBox Spike, vbInformation, "Action report"
End Sub
If my approach shows promise more speed could be gained by reading column B:B into another array and use a MATCH function instead of Find. In that way "Customer Master" would need to be accessed only once. Of course, you could also gain a little time by suspending ScreenUpdating during execution.
No VBA required. Use Formula + Conditional formatting
Entering the formula
Put this formula in BW3 and copy it down. Change SAMPLE.xlsx to the relevant file.
=IF(LEFT(D3,3)=625,XLOOKUP(A3,'[SAMPLE.xlsx]Customer Master'!$B:$B,'[SAMPLE.xlsx]Customer Master'!$AD:$AD),XLOOKUP(A3,'[SAMPLE.xlsx]Customer Master'!$B:$B,'[SAMPLE.xlsx]Customer Master'!$AH:$AH))
Setting up Conditional Formatting
Select the relevant range, starting for row 3.
Click on Home | Conditional formatting | New Rule | Use formula to determine which cells to format
Enter the formula =BW3<>BX3 and set the relevant color.
And you are done.
If you still want VBA then also you do not need any kind of loop or Autofill. You can enter the formula via VBA in all the cells in 1 GO! Here is an example (UNTESTED)
With shMacro
lrow = .Range("D" & .Rows.Count).End(xlUp).Row
.Range("BW3:BW" & lrow).Formula = "=IF(LEFT(D3,3)=625,XLOOKUP(A3,'[SAMPLE.xlsx]Customer Master'!$B:$B,'[SAMPLE.xlsx]Customer Master'!$AD:$AD),XLOOKUP(A3,'[SAMPLE.xlsx]Customer Master'!$B:$B,'[SAMPLE.xlsx]Customer Master'!$AH:$AH))"
End With
For conditional formatting you can use this code
With shMacro.Range("BW3:BW" & lrow)
.FormatConditions.Add Type:=xlExpression, Formula1:="=BW3<>BX3"
.FormatConditions(.FormatConditions.Count).SetFirstPriority
With .FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = 255
.TintAndShade = 0
End With
.FormatConditions(1).StopIfTrue = False
End With
So basically your entire code can be written as
With shMacro
lrow = .Range("D" & .Rows.Count).End(xlUp).Row
With .Range("BW3:BW" & lrow)
.Formula = "=IF(LEFT(D3,3)=625,XLOOKUP(A3,'[SAMPLE.xlsx]Customer Master'!$B:$B,'[SAMPLE.xlsx]Customer Master'!$AD:$AD),XLOOKUP(A3,'[SAMPLE.xlsx]Customer Master'!$B:$B,'[SAMPLE.xlsx]Customer Master'!$AH:$AH))"
DoEvents
.FormatConditions.Add Type:=xlExpression, Formula1:="=BW3<>BX3"
.FormatConditions(.FormatConditions.Count).SetFirstPriority
With .FormatConditions(1).Interior
.PatternColorIndex = xlAutomatic
.Color = 255
.TintAndShade = 0
End With
.FormatConditions(1).StopIfTrue = False
End With
End With
I have encountered a few issues with some code in VBA. I am trying to have the changes made to a cells on an excel sheet show up in comments on the cell the change was made to and I wish for these changes to be stored in a list so I can view them all later. I have tried lots of different pieces of code I have found to try and implement it into the code but none have worked.
Any ideas on how to get this to work?
Worksheet
The below code is what I am currently using
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Adding As Boolean, Finding As Boolean, Subtracting As Boolean
Dim f As Range, v
Select Case Target.Address(True, True)
Case "$A$4": Adding = True
Case "$C$4": Subtracting = True
Case "$E$4": Finding = True
Case Else: Exit Sub
End Select
v = Trim(Target.Value)
If Len(v) = 0 Then Exit Sub
Set f = Me.Range("C8").Resize(1000, 1).Find(v, lookat:=xlWhole)
If Adding Then
If f Is Nothing Then
'not found: add as new row
Set f = Me.Cells(Rows.Count, 3).End(xlUp).Offset(1, 0)
f.Value = v
End If
f.Offset(0, 1).Value = f.Offset(0, 1).Value + 1
doDate f.Offset(0, 2)
Target.Value = ""
ElseIf Subtracting Then
If f Is Nothing Then
MsgBox v & " not found for subtraction!"
Else
f.Offset(0, 1).Value = f.Offset(0, 1).Value - 1
doDate f.Offset(0, 3)
Target.Value = ""
End If
Else 'finding
If Not f Is Nothing Then
f.EntireRow.Select
Target.Value = ""
Else
MsgBox v & " not found."
End If
End If
If Adding Or Subtracting Then Target.Select
End Sub
Sub doDate(c As Range)
With c
.NumberFormat = "m/d/yyyy h:mm AM/PM"
.Value = Now
End With
End Sub
I have implemented a few formulas on the worksheet but don't see any reason why it would matter in this situation since they only track quantity of items with the same unique identifier.
I also tried some code that added comments to the cells as they were changed that worked but always returned the previous cell value as blank. It is not actually added into the current code though.
Option Explicit
Public preValue As Variant
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
Target.ClearComments
Target.AddComment.Text Text:="Previous Value was " & preValue & Chr(10) & "Revised " & Format(Date, "mm-dd-yyyy") & Chr(10) & "By " & Environ("UserName")
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Target = "" Then
preValue = "a blank"
Else: preValue = Target.Value
End If
End Sub
By and large, the code below should do what you want. I marveled at your use of A4 and C4 to express addition and subtraction. As it is, whatever you change in those two cells, apart from clearing them, will result in a quantity of 1 being added or subtracted. I would have expected that a quantity must be entered there which is processed. If the quantity is fixed at 1 the system appears too elaborate.
Anyway, here's the code. I guess you'll be able to modify it to better suit your needs.
Private Sub Worksheet_Change(ByVal Target As Range)
' 038
Dim LookUp As Variant ' subject
Dim Action As Variant ' add = 1, subtract = -1, find = 2
Dim Fnd As Range ' Result of Find method
Dim Txt As String ' comment text
With Target
If (.Row <> 4) Or (.CountLarge > 1) Then Exit Sub
LookUp = Cells(4, "E").Value
On Error Resume Next
Action = Array(0, 1, 0, -1, 0, 2)(.Column)
End With
If Action And (LookUp <> "") Then
' C8 to end of column C
With Range(Cells(8, "C"), Cells(Rows.Count, "C").End(xlUp))
Set Fnd = .Find(LookUp, .Cells(.Cells.Count), xlValues, xlWhole, xlByRows)
End With
End If
If Fnd Is Nothing Then
Select Case Action
Case -1
MsgBox """" & LookUp & """ not found.", vbInformation, "Can't subtract"
Action = -2
Case 2
MsgBox """" & LookUp & """ not found.", vbInformation, "No record"
Action = -2
Case Else
Set Fnd = Cells(Rows.Count, "C").End(xlUp).Offset(1)
Fnd.Value = LookUp
End Select
End If
With Fnd
If Abs(Action) <> 2 Then
With .Offset(0, 1)
If .Comment Is Nothing Then
.AddComment
Else
Txt = Chr(10)
End If
Txt = "Previous Qty = " & .Value & Chr(10) & _
"Revised " & Format(Date, "mm-dd-yyyy") & Chr(10) & _
"by " & Environ("UserName") & Txt
.Comment.Text Txt, 1, False
.Value = Val(.Value) + Action
With .Offset(0, 2)
.NumberFormat = "m/d/yyyy h:mm AM/PM"
.Value = Now
End With
End With
ElseIf Action = 2 Then
.EntireRow.Select
End If
End With
If Action <> 2 Then Target.Select
End Sub
I have a Userform with a listbox for which I am using conditional logic to determine output values to the sheet of selected or non-selected items in the listbox. The issue is that when the Textbox (Tbl_AliasName) is blank, the code executes this:
ElseIf .Selected(k) = True And Tbl_AliasName = vbNullString Then
lstbxRow = lstbxRow + 1
Worksheets("New TRAX").Cells(lstbxRow, 3) = Trim(Cells(2, 1).Value2) & "." & .Column(1, k)
But if Tbl_AliasName is not blank then the code does nothing, but it is supposed to do this:
ElseIf .Selected(k) = True And Tbl_AliasName <> vbNullString Then
lstbxRow = lstbxRow + 1
Worksheets("New TRAX").Cells(lstbxRow, 3) = Tbl_AliasName & "." & .Column(1, k)
I have used several variations of If statements, and non of which have worked.
Below is My Code:
Option Explicit
Public Tbl_AliasName As String
Tbl_AliasName = Trim(UserForm_Finder.txtConcat.Value)
Private Sub BtnConcat_Click()
Dim k As Long, lstbxRow As Long, LR As Long
lstbxRow = 1
'****************
'This if statement works perfectly
If (Cells(2, 1).Value2 = vbNullString Or Cells(2, 2).Value2 = vbNullString) _
And Tbl_AliasName = vbNullString Then
MsgBox "You must Search for a Table or Column first.", _
vbExclamation, "Error Encountered"
Exit Sub
ElseIf (UserForm_Finder.ListBx_TblsCols.ListCount = 0 And Tbl_AliasName <> vbNullString) Then
MsgBox "You must Search for a Table or Column first.", _
vbExclamation, "Error Encountered"
'(Cells(2, 1).Value2 = vbNullString Or Cells(2, 2).Value2 = vbNullString) And _
Exit Sub
End If
With UserForm_Finder.ListBx_TblsCols
For k = 0 To .ListCount - 1
'****************
This is where the problems begin
If .Selected(k) = False Then
MsgBox "You must Select 1 or more items from the list box.", _
vbExclamation, "Error Encountered"
Exit Sub
ElseIf .Selected(k) = True And Tbl_AliasName <> vbNullString Then
lstbxRow = lstbxRow + 1
Worksheets("New TRAX").Cells(lstbxRow, 3) = Tbl_AliasName & "." & .Column(1, k)
ElseIf .Selected(k) = True And Tbl_AliasName = vbNullString Then
lstbxRow = lstbxRow + 1
Worksheets("New TRAX").Cells(lstbxRow, 3) = Trim(Cells(2, 1).Value2) & "." & .Column(1, k)
End If
Next k
End With
End Sub
My goal is to do the following:
If a Textbox (Tbl_AliasName) is not blank and the user has selected one or more items in the listbox (ListBx_TbleCols) then concatenate the Tbl_AliasName to the selected items in the listbox
If Tbl_AliasName is blank, then use the value in Cells(2,1) to concatenate to the selected Items in the list box.
I have tried the following additions:
Dim LstBxItemSelected As Boolean
'This was placed in the for loop
LstBxItemSelected = True
'this was placed outside the for loop
If LstBxItemSelected = False Then
MsgBox "You must Select 1 or more items from the list box.", _
vbExclamation, "Error Encountered"
Exit Sub
End If
Is there a better way to tell if items are selected, because I feel that the way I have it structured in my loop, the code will throw the error if everything isn't selected? Thank you in advance for any ideas, answers, or suggestions!
Note: The Listbox is populated by the click of another button on the userform which calls the following sub:
Sub FillLstBxCols()
Dim ListBx_Target As MSForms.ListBox
Dim rngSource As Range
Dim LR As Long
If Cells(2, 1).Value2 <> vbNullString Then
LR = Worksheets("New TRAX").Cells(Rows.Count, 2).End(xlUp).Row
'Set reference to the range of data to be filled
Set rngSource = Worksheets("New Trax").Range("A" & 2 & ":" & "B" & LR)
'Fill the listbox
Set ListBx_Target = UserForm_Finder.ListBx_TblsCols
With ListBx_Target
.RowSource = rngSource.Address
End With
End If
End Sub
Hard to say without sample data and expected results, but I think this is what you're looking for:
Private Sub btnConcat_Click()
Dim ws As Worksheet
Dim bSelected As Boolean
Dim sConcat As String
Dim i As Long, lRowIndex As Long
Set ws = ActiveWorkbook.Sheets("New TRAX")
lRowIndex = 1
bSelected = False
sConcat = Trim(Me.txtConcat.Text)
If Len(sConcat) = 0 Then sConcat = Trim(ws.Cells(2, "A").Value)
If Len(sConcat) = 0 Then
MsgBox "You must Search for a Table or Column first.", vbExclamation, "Error Encountered"
Exit Sub
End If
For i = 0 To Me.ListBx_TblsCols.ListCount - 1
If Me.ListBx_TblsCols.Selected(i) Then
If bSelected = False Then
bSelected = True
ws.Range("C2", ws.Cells(ws.Rows.Count, "C")).Clear 'clear previous concat results (delete this line if not needed)
End If
lRowIndex = lRowIndex + 1
ws.Cells(lRowIndex, "C").Value = sConcat & "." & Me.ListBx_TblsCols.List(i)
End If
Next i
If bSelected = False Then MsgBox "Must select at least one item from the list"
End Sub
I've got a Worksheet titled "Survey". I'm trying to attach checkboxes to all of the cells in column A that are next to answers, and for some reason I'm getting an "object required" error. The 4 lines near the beginning, starting with "Set rng =", are highlighted.
I'm pretty new to VBA, so I'm not sure if this is just a simple syntax issue that I'm not seeing. I've tried searching for the proper format, to no avail. Can anyone help? Here's the code that I've got:
Sub AddCheckBox()
Dim rng As Range
Dim rcell As Range
Set rng = Survey.Range("A7:A10,A13:A17,A21:A25,A28:A33" _
& "A36:A43, A48,A51:A56,A60:A66,A69:A73,A76:A80" _
& "A83:A87, A90:A94, A97:A102, A105:A113, A116:A122, A125:A131" _
& "A134:A141,A145:A149, A152:A158, A161:A165")
DelCheckBox
For Each rcell In rng
With ActiveSheet.CheckBoxes.Add(rcell.Left, _
rcell.Top, rcell.Width, rcell.Height)
.LinkedCell = rcell.Offset(, 0).Address(External:=True)
.Interior.ColorIndex = 14 'or xlNone or xlAutomatic
.Caption = ""
.Border.Weight = xlThin
End With
Next
With Range("A7:A10,A13:A17,A21:A25,A28:A33" _
& "A36:A43, A48,A51:A56,A60:A66,A69:A73,A76:A80" _
& "A83:A87, A90:A94, A97:A102, A105:A113, A116:A122, A125:A131" _
& "A134:A141,A145:A149, A152:A158, A161:A165")
.Rows.RowHeight = 15
End With
End Sub
Sub DelCheckBox()
For Each cell In Range("A1:A166")
Worksheets("Survey").CheckBoxes.Delete
Next
End Sub
You're missing the commas at the end of your lines. Try this:
Set rng = Survey.Range("A7:A10,A13:A17,A21:A25,A28:A33," _
& "A36:A43, A48,A51:A56,A60:A66,A69:A73,A76:A80," _
& "A83:A87, A90:A94, A97:A102, A105:A113, A116:A122, A125:A131," _
& "A134:A141,A145:A149, A152:A158, A161:A165")
Note, you'll have to make the same change where you have the With Range("....") block as well. Also, the above code does not reflect the validity of the rest of what you're trying to do...just that one error.
EDIT to fix issues down the road...
Try this all of this code and see if it does what you're after:
Sub test()
Dim rng As Range
Dim rcell As Range
Set rng = Sheets("Survey").Range("A7:A10,A13:A17,A21:A25,A28:A33," _
& "A36:A43, A48,A51:A56,A60:A66,A69:A73,A76:A80," _
& "A83:A87, A90:A94, A97:A102, A105:A113, A116:A122, A125:A131," _
& "A134:A141,A145:A149, A152:A158, A161:A165")
DelCheckBox
For Each rcell In rng
With Sheets("Survey").CheckBoxes.Add(rcell.Left, _
rcell.Top, rcell.Width, rcell.Height)
.LinkedCell = rcell.Offset(, 0).Address(External:=True)
.Interior.ColorIndex = 14 'or xlNone or xlAutomatic
.Caption = ""
.Border.Weight = xlThin
End With
Next
rng.Rows.RowHeight = 15
End Sub
Sub DelCheckBox()
Sheets("Survey").DrawingObjects.Delete
End Sub