I have 1 userform for login called "LoginForm" and 3 additional userforms "AMForm", "FMForm" and "HRMForm" that open up if the user's details are correct. There are 3 spreadsheets "AMChoices", "FMChoices" and "HRMChoices" where the contents from the 3 additional userforms are recorded into the relevant spreadsheet i.e. FMForm into FMChoices.
To specify the user, their UserID appears in the relevant spreadsheet if their credentials are accepted. For example, if is userform "AMForm" their UserID is entered into the next available cell in column B in "AMChoices" (starting at B3). As there are multiple users logging in, it enters to the next empty row.
The code I have works perfectly. However, on each userform "AMForm", "FMForm" and "HRMForm" there is a "quit" button. So I want it to delete the recently entered UserID.
How can I code this? I have entered the code I use to enter the UserID into the spreadsheet from the LoginForm. Please let me know :)
Private Sub btnAMLogout_Click()
If MsgBox("Are you sure you want to quit? Press Yes to proceed and No to cancel.", vbYesNo) = vbYes Then
Unload Me
End If
End Sub
If aCell.Offset(, 4) = "SBUB10" Then
AMForm.Show
With Worksheets("AMChoices")
LastRow = .Range("B" & .Rows.CountLarge).End(xlUp).Row + 1
If LastRow < 3 Then LastRow = 3
.Cells(LastRow, "b") = WorksheetFunction.Proper(ID)
End With
The snippet of code you've shown writes the ID into the worksheet. To remove it, you need to find it and blank out the cell it is in. This action can be performed either before theUnload Me call or after it. The code you have needs some modifications:
Private Sub btnAMLogout_Click()
If MsgBox("Are you sure ...", vbYesNo) = vbYes Then
Unload Me
' Let's say the new code goes here. The last ID (whichever it is) will be removed.
With Worksheets("AMChoices")
LastRow = .Range("B" & .Rows.CountLarge).End(xlUp).Row ' no need for: + 1
If LastRow < 3 Then Exit Sub ' no need for: LastRow = 3
.Cells(LastRow, "b") = "" ' no need for: WorksheetFunction.Proper(ID)
End With
End If
End Sub
Now, since you've mentioned multiple users, it might be a bit more complicated because you need to find the cell with the ID in question (it might not be the last one!) and then delete it. The "deleting" could be just emptying the cell (as above) or deleting the whole row of that cell, or something else--I do not know your situation well enough to say which it is.
Anyway, to look for the last occurrence of that ID in column "B:B" you need to test the cells in the column to have that ID, starting from the last cell and going up, one cell at a time, something like
For i = LastRow to 3 Step -1
If .Cells(i, "B") = WorksheetFunction.Proper(ID) Then
.Rows(i).Delete
Exit For
End If
Next
I sure hope this helps.
Related
Guy, I am beginner for VBA language, and I have a question to stuck on it.
How to make a macro script to check if ANY rows of column B is input word of "C" AND ANY rows of column C is empty, then it will trigger to highlight this row with color and prompt up the message box to remind user to correct it.
Also, the column D is using the formula and cell by cell method to check the above requirement.
=IF(ISBLANK(B4),"",IF(OR(B4="C",B4="O"),IF(AND(B4="C", ISBLANK(C4)),"WARNING: Case Closed! Please Write Down Resolution!",""),"ERROR: Invalid Value - Status! Please Input The Right Value!"))
For example, the row 4 meet up requirement and affected.
Is there way to do so?
Please help. Thanks.
UPDATE:Thanks Variatus!
When I save the file, it prompt up this message box. What can I do? Thanks.
Macro Screen
Error
Under normal circumstances you would be asked to show more of an own effort before receiving help on this forum, including from me. But apparently circumstances aren't normal. So, here we go. Paste this procedure to a standard code module (it's name would be a variation of Module1 by default).
Option Explicit
Sub MarkErrors()
' 283
Dim Spike() As String
Dim i As Long ' index of Spike
Dim Rl As Long ' last used row
Dim R As Long ' loop counter: rows
Application.ScreenUpdating = False
With Sheet1 ' this is the sheet's CodeName (change to suit)
.UsedRange.Interior.Pattern = xlNone ' remove all existing highlights
Rl = .Cells(.Rows.Count, "A").End(xlUp).Row
ReDim Spike(1 To Rl)
For R = 2 To Rl
If Trim(.Cells(R, "B").Value) = "C" Then
If IsEmpty(.Cells(R, "C")) Then
.Range(.Cells(R, "A"), .Cells(R, "D")).Interior.Color = vbYellow
i = i + 1
Spike(i) = "Row " & R
End If
End If
Next R
End With
Application.ScreenUpdating = True
If i Then
ReDim Preserve Spike(1 To i)
MsgBox "Status errors were found in the following entries:-" & vbCr & _
Join(Spike, "," & vbCr), vbInformation, "Corrections required"
End If
End Sub
Pay attention to the specified worksheet Sheet1. This is a CodeName, and it is a default. Excel will create a sheet by that name when you create a workbook. The CodeName doesn't change when the user changes the tab name but you can change it in the VB Editor. It's the (Name) property of the worksheet.
Install the procedure below in the code sheet of Sheet1 (not a standard code module and therefore not the same as where you installed the above code. This module is created by Excel for each sheet in every workbook. Use the existing one.
Private Sub Worksheet_Activate()
' 283
MarkErrors
End Sub
This is an event procedure. It will run automatically whenever Sheet1 is activated (selected). So, under normal circumstances you shouldn't ever need to run the first procedure manually. But I've already talked about circumstances. They aren't always normal. :-)
To start, I am using Excel 2016 on Windows 10.
I have a spreadsheet in Excel that utilizes two macros to either insert data based on a userform or delete all data from the spreadsheet when someone wants to clear it. The focus of this question is the program that clears the data (seen below), though I will be discussing the other one as well.
Sub ClearData()
ToDelete = MsgBox("Are you sure you want to delete all data?", vbYesNo, "Are you sure?")
if ToDelete = vbYes Then
ActiveSheet.Unprotect "Password"
Do While Range("A2").Value <> ""
Range("A2:J2").Delete Shift:=xlUp
Loop
ActiveSheet.Protect "Password"
End If
End Sub
The code is pretty straight forward. It asks the user to confirm they want to delete all the data, and if they do, it unlocks the sheet, continuously deletes the second row until there are no more rows, and then it locks the sheet back.
Problem: So let's say I have 10 rows of data in my spreadsheet and hit the button that leads to the ClearData() sub. In this case, the first row deletes, and then the macro stops entirely, leaving 9 rows of data. Now if I hit the ClearData() button again, the macro executes flawlessly and deletes the remaining 9 rows.
I thought maybe the issue was with the locking and unlocking the spreadsheet portion of the code. So I manually unlocked the sheet and clicked the button, and the same bug occurred.
Another similar issue that occasionally occurs with the "insert data" macro is that it will only add data to one cell (not even a full row, just the first cell). Then, if I run the program again and enter the same exact information into the userform, all of it fills in correctly. In both of these cases, the macro runs through a few lines of code until it executes the first line of code that actually updates the spreadsheet and then completely exits the code without executing any further lines. Also note that no error messages occur, either.
One thing to note is that this problem appears to be intermittent. I just tried it again, and the data is filling out and clearing correctly. There is one thing I can do that will cause the "insert data" macro to have the problem. If I change the code and save it again, even if the code I changed was irrelevant (e.g. adding a space to a comment), then the insert data error will occur on the next execution.
Not an actual answer to your question, but a suggestion to help debuging it.
Add a trap to detect the error condition, and break into debug mode, so you can examine the state of things.
Sub ClearData()
Dim ToDelete As VbMsgBoxResult
Dim RowCount As Long
ToDelete = MsgBox("Are you sure you want to delete all data?", vbYesNo, "Are you sure?")
If ToDelete = vbYes Then
ActiveSheet.Unprotect "Password"
Do While Range("A2").Value <> ""
Range("A2:J2").Delete Shift:=xlUp
RowCount = RowCount + 1
Loop
If RowCount = 1 Then Stop
ActiveSheet.Protect "Password"
End If
End Sub
It the loop ends after one deletion, the code will break on the Stop command. You can then examine the state of your sheet and the value of cell A2, which may (or may not!) shed some light.
Again not an answer, but an alternative method:
This assumes two things
- There is no additional data you want to keep below the first blank row in column A
- There is no additional data you want to keep to the right of column J
If either of these assumptions are wrong, the code can easily be adjusted to suit
Sub ClearData()
Dim rng As Range
If MsgBox("Are you sure you want to delete all data?", vbYesNo, "Are you sure?") <> vbYes Then Exit Sub
With ActiveSheet
Set rng = .Range(.Cells(.Rows.Count, 1).End(xlUp), .Cells(2, 1))
' account for possibility there are no data rows
If rng.Row = 1 Then Exit Sub
.Unprotect "Password"
rng.EntireRow.Delete
.Protect "Password"
End With
End Sub
I am working in Excel and trying to create a command button that will update the value in a cell based on the current value of the cell, down the entire column.
More specifically, I have a column with location IDs which are integers. At a click, I want all cells within that column that contain the values 1 or 2 to be changed to 10. Then, I want to run a prerecorded sort macro.
I have found information on cascading If statements, which seems to be the key. I thought something like the following might work, but it keeps telling me I have a logic error.
Private Sub CommandButton1_Click()
If Range("LocationID") = 1 Then
Range("LocationID") = 10
Else
If Range("LocationID") = 2 Then
Range("LocationID") = 10
End If
End Sub
Location is the column I am trying to search and change.I have not added my sort macro into this yet, because I assume that works like any other button that calls a macro.
This is probably really basic, but VBA is totally foreign to me. I've been banging my head against this problem all morning. Thanks for the help!
It sounds like you mean something like this:
Private Sub CommandButton1_Click()
Dim lRow As Long
lRow = 1
Do Until Range("A" & lRow) = ""
Select Case Range("A" & lRow)
Case 1, 2
Range("A" & lRow) = 10
End Select
lRow = lRow + 1
Loop
End Sub
Note: I just guessed that it's column A. You will want to change that in all 3 places to the column that has the value you want.
Good morning,
I am in yet another rut and need some help. I have created a user form that allows a user to delete an entire rows worth of data on a second sheet (rawdata). Everything works fine using the code below, however the combo box ONLY shows the row number. I am in desperate need of changing the column so it will show the project names of the rows that need to be deleted.
Example:
Row: Project
1 Alpha
2 Beta
I would like the combo box to show Alfa and Beta and have the user be able to select the row they would like to delete based on that criteria.
The code below unhides and then hides the sheet that I want this deletion to occur on. This was done with purpose.
Private Sub ComboBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Dim lRw As Long
ActiveWorkbook.Sheets("RAWDATA").Visible = xlSheetVisible
'get the row number. add 1 because ListIndex starts at zero
lRw = Me.ComboBox1.ListIndex + 1
ActiveWorkbook.Sheets("RAWDATA").Select
Cells(lRw, 1).EntireRow.Delete
ActiveWorkbook.Sheets("RAWDATA").Visible = xlSheetHidden
End Sub
Private Sub CommandButton1_Click()
End Sub
Private Sub UserForm_Initialize()
'assumes data starts in A1 and has a header row
Me.ComboBox1.List = ActiveWorkbook.Sheets("RAWDATA").Cells(1, 1).CurrentRegion.Offset(1).Value
End Sub
Thanks for the help!
Change .Cells(1, 1) to .Cells(1, 2)
The Cells() method gives the code co-ordinates to a specific range using the row and the column number like so:
Cells(r, c)
so in your original code, the .Cells(1, 1) points to "A1" and then uses .CurrentRegion to get all cells within the region of A1.
By replacing the column number and using .Cells(1, 2) we tell it to look at "B1" instead - therefore shifting the column over to the right.
EDIT:
You could apply this logic to the Offset(r, c) function to shift the returned value over by 1 column - so:
.Cells(1, 1).CurrentRegion.Offset(1, 1)
This will more than likely be the culprit as the .Cells() method will point to a specific cell, but the .CurrentRegion() method will return the same result regardless unless we offset it.
First day, new job, don't want to fall flat in front of my boss on the first task I've been given. I've tried various IF THEN, FOR & DO statements but can't get quite the behaviour I need.
I have data from column A to AH. I want to click a button, which would cause a loop to check the contents of every cell on column D and then to clear the contents of that row if it comes back empty.
Sub delDemptyrows()
Dim i&
For i = 1 To ActiveSheet.UsedRange.Rows.Count
If Cells(i, 4).Value = vbNullString Then Cells(i, 4).EntireRow.ClearContents '4 = D column
Next
End Sub
not tested, so make backup before use.