Match Textbox entry with cells to populate column with Userform data - excel

I currently have multiple spreadsheets with a row of dates for each employee.
Within the userform that pops up modified for each employee, there is a place for the date at the top, and they fill out the rest of the information and then submit.
Is there a way to match up the date on the sheet with the one on the userform to populate the column underneath?

Assuming you have a textbox on your form that you type the date into.
This first bit of code is ensuring you have a date in the textbox rather than anything else.
Paste this into a normal module. You can place it in the form, but in a module allows it to be used by any other forms you may have that contain a date.
Public Sub FormatDate(ctrl As Control)
Dim dDate As Date
Dim IsDate As Boolean
On Error GoTo ERR_HANDLE
If Replace(ctrl.Value, " ", "") <> "" Then
On Error Resume Next
dDate = CDate(ctrl.Value)
IsDate = (Err.Number = 0)
On Error GoTo -1
On Error GoTo ERR_HANDLE
If IsDate Then
ctrl.Value = Format(ctrl.Value, "dd-mmm-yyyy")
ctrl.BackColor = RGB(255, 255, 255)
Else
ctrl.BackColor = RGB(255, 0, 0)
End If
End If
EXIT_PROC:
On Error GoTo 0
Exit Sub
ERR_HANDLE:
MsgBox Err.Number & ": " & Err.Description, vbOKOnly, "FormatDate()"
Resume EXIT_PROC
End Sub
Place this on the form as the AfterUpdate event for your textbox:
Private Sub txtDate_AfterUpdate()
On Error GoTo ERR_HANDLE
With Me
FormatDate .txtDate
End With
EXIT_PROC:
On Error GoTo 0
Exit Sub
ERR_HANDLE:
MsgBox Err.Number & ": " & Err.Description, vbOKOnly, "txtDate_AfterUpdate()"
Resume EXIT_PROC
End Sub
Any valid date will be formatted as dd-mmm-yyyy, any invalid date will turn the background of the control red.
Next you need to find the date on row 1 of your sheet. Again this can be kept in a normal module so you can use it outside of the form:
Public Function FindDate(DateValue As Date) As Range
Dim rFound As Range
With Sheet2
Set rFound = .Rows(1).Find(DateValue, .Cells(1, 1), xlValues, xlWhole)
If rFound Is Nothing Then
Set rFound = .Cells(1, .Columns.Count).End(xlToLeft).Offset(, 1)
End If
End With
Set FindDate = rFound
End Function
This will return the cell that the date is in or the last blank cell on row 1 if the date isn't found.
I'm not sure if you want this bit, but this then finds the last cell containing data in a specified column number:
Public Function LastCell(wrksht As Worksheet, Col As Long) As Range
Dim lLastRow As Long
On Error Resume Next
lLastRow = wrksht.Columns(Col).Find("*", , , , xlByColumns, xlPrevious).Row
On Error GoTo 0
If lLastRow = 0 Then lLastRow = 1
Set LastCell = wrksht.Cells(lLastRow, Col)
End Function
Now you just need to attach the code to your find button to return the first blank cell beneath the date you specify:
Private Sub btnFind_Click()
Dim rFoundCell As Range
'First blank cell beneath date.
Set rFoundCell = LastCell(Sheet1, FindDate(CDate(Me.txtDate)).Column).Offset(1)
End Sub
If you just wanted to find the date you can just use:
Set rFoundCell = FindDate(CDate(Me.txtDate))
The help file on Find is here.
Finding dates can be problematic in Excel:
excel-vba-range-find-date-that-is-a-formula
DateTimeVBA

Related

Add a text to an existing cell

I'm trying to create a function in VBA to add a text to an existing cell.
, 
I want to add "Brand" to cells in the first column. I want to use this function in any cell where I enter the formula.
I'm very new to VBA. I tried searching the internet but couldn't find a simple solution for my level. Could anyone please help me with this? 
Thank you
Add a new module in the Visual Basic Editor (VBE).
Add this code to the module:
Option Explicit
Public Sub Add_Brand()
Dim Cell As Range
For Each Cell In Selection
Cell = "Brand " & Cell
Next Cell
End Sub
Select a range of cells, go to View > Macros on the toolbar and run the Add_Brand macro.
Edit: I should add that if the selected range of cells contain a formula then this will overwrite the formula with the new value.
Edit 2: If you did have formula (not an array formula) I guess you could use this code....
Public Sub Add_Brand()
Dim Cell As Range
For Each Cell In Selection
If Cell.HasFormula Then
Cell.Formula2 = "=""Brand "" & " & Mid(Cell.Formula2, 2, Len(Cell.Formula2))
Else
Cell = "Brand " & Cell
End If
Next Cell
End Sub
A Worksheet Change: Add a Prefix
The following code needs to be copied to the sheet module of the worksheet where it is meant to be applied e.g. Sheet1 (not in a standard module e.g. Module1 nor in the ThisWorkbook module).
It runs automatically: whatever you attempt to write to A2:A1048576 gets the "Brand " prefix.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Const FIRST_CELL As String = "A2"
Const PREFIX As String = "Brand "
On Error GoTo ClearError
Dim trg As Range
With Me.Range(FIRST_CELL)
Set trg = .Resize(Me.Rows.Count - .Row + 1)
End With
Dim irg As Range: Set irg = Intersect(trg, Target)
If irg Is Nothing Then Exit Sub
Dim pLen As Long: pLen = Len(PREFIX)
Dim iCell As Range, iString As String
Application.EnableEvents = False
For Each iCell In irg.Cells
iString = CStr(iCell.Value)
If Len(iString) > 0 Then
'If InStr(1, iString, PREFIX, vbTextCompare) <> 1 Then
iCell.Value = PREFIX & iString
'End If
End If
Next iCell
ProcExit:
On Error Resume Next
If Not Application.EnableEvents Then Application.EnableEvents = True
On Error GoTo 0
Exit Sub
ClearError:
Debug.Print "Run-time error '" & Err.Number & "':" & vbLf & Err.Description
Resume ProcExit
End Sub
Select the first cell you want to change before running the code.
Sub insertBrand()
Do While ActiveCell.Value <> ""
ActiveCell.Value = "Brand " & ActiveCell.Value
Cells(ActiveCell.Row + 1, ActiveCell.Column).Activate
Loop
End Sub

Press a button to sum a range of cells

In column (T2) going down I have the category "money spent". In the next column (U2) I have the date "mm/dd/yy". I want to take the money spent between two dates, sum them up and display it in a message box. How do I do this?
My code so far is:
Sub Button()
Dim myRange
Dim Results
Dim Run As Long
myRange = Worksheet("sheet1").Range ("T2", "5")
Results = WorksheetFunction.Sum(myrange)
MsgBox (Results)
End Sub
This will prompt you for two single cell date selections, and then offset to get the total. This is assuming the dates you select are in Column U so it can add up values in Column T. If you are planning on entering dates into another cell you will need to use find or something to do get the range.
If you want to use a button just assign the Sub.
Option Explicit
Sub CalculateTotal()
Dim startrange As Range
Dim endrange As Range
On Error GoTo errhandler
Dim dateselected As Boolean
dateselected = False
'Make sure one date per range is selected
Do Until dateselected = True
Set startrange = Application.InputBox("Please Enter Single Cell Starting Date Range", , , , , , , 8)
Set endrange = Application.InputBox("Please Enter Single Cell Ending Date Range", , , , , , , 8)
If IsDate(startrange.Value) And IsDate(endrange.Value) Then
dateselected = True
End If
Loop
With ActiveSheet
Dim daterange As Range
Set daterange = .Range(startrange, endrange) 'Combine Ranges
Dim cell As Range
Dim total As Double
total = 0
For Each cell In daterange.Offset(0, -1)
total = total + cell.Value ' Get Total
Next cell
MsgBox "Total value of daterange: " & total
End With
Exit Sub
errhandler:
Select Case Err.Number
Case 424 ' Add in other cases as needed
MsgBox "Range selection cancelled, Exiting"
Exit Sub
Case Else
MsgBox "Unhandled error: " & Err.Number & vbNewLine & Err.Description
Exit Sub
End Select
End Sub

Using VBA code to return a cell to specific row

just starting out with VBA and got stuck on this issue;
I have a resource sheet for people/equipment. The available equipment rows are lower in the sheet than the main work plan. I want to be able to select an item of equipment from the work plan and return it to the available equipment rows. The code below is what I have so far but it's not working. Not sure if it's because I have asked it to select activecell for 2 ranges?
Rng1 is the cell I want to move.
Rng2 is in the same column as Rng1 but lower down (I am trying to reference Rng1 with the same value in Column A to select the correct row).
Hope that all makes sense :)
Public Sub Return_Equipment()
Dim Name1 As String, Name2 As String, NameTemp As String, NameRef As String, Rng1 As Range, Rng2 As Range, Rng3 As Range, StatusVar As Boolean
If IsEmpty(ActiveCell) Then
MsgBox "Please select an item of equipment", vbOKOnly + vbInformation, "Selection Error"
Exit Sub
End If
On Error GoTo errorhandler
Set Rng1 = ActiveCell
Do
NameRef = Intersect(ActiveCell.EntireRow, ActiveCell.CurrentRegion.Columns(1)).Value
If (ActiveCell.Value = NameRef) = False Then
ActiveCell.Offset(1, 0).Select
End If
Loop Until (ActiveCell.Value = NameRef) = True
ActiveCell
Set Rng2 = ActiveCell
Set Rng3 = Application.InputBox("Please select last date for returning", Type:=8)
On Error GoTo 0
StatusVar = False
If IsEmpty(Rng2) Then
StatusVar = True
If WorksheetFunction.CountA(Range(Rng2.Address).Resize(, Range(Rng1.Address & ":" & Rng3.Address).Columns.Count)) <> 0 Then
MsgBox "Not all cells are empty in the destination row! Please start again.", vbCritical + vbOKOnly, "Cell Allocation Error"
Exit Sub
End If
End If
'...
'errorhandler:
'...
End Sub
I'll elaborate a little more regarding what I'm trying to do;
In the picture below I want to return the trailer "Trailer 37U52 L4386 (for trk Ranger)" from cells IV:114 & IW:114 to IV:261 & IW:262 and clear data from IV:114 & IW:114.
I start by selecting IV:114 and running the code. The code sets IV:114 to Rng1. Then it looks at Column A for the corresponding value (in this case A:261) and sets Rng2 as the cell in that row in the Rng1 column (IV:261). The end date is selected using the input box and sets Rng3 as the last column I want this change to be applied to (in the same row as Rng1) In this case I select a cell in column IW.
It is then supposed to relabel cells IV:261 & IW:261 with the values from IV:114 & IW:114 and clear data from IV:114 & IW:114. What I see it doing when I run the code is setting IV:114 & IW:114 to "Temp Value" and then relabeling it back to "Trailer 37U52 L4386 (for trk Ranger)"
Does that help anyone to see what is wrong with my code?
Picture of scenario
According to your description, that one should work.
It is not the cleanest version (you should mention worksheet...)
Public Sub Return_Equipment()
Dim Name1, Name2, NameRef As String
Dim Rng1, Rng2, Rng3 As Range
Dim i, j as Long
If IsEmpty(ActiveCell) Then
MsgBox "Please select an item of equipment", vbOKOnly + vbInformation, _
"Selection Error"
Exit Sub
End If
On Error GoTo errorhandler
Set Rng1 = ActiveCell
Set Rng2 = Cells(1, 1)
j = ActiveSheet.UsedRange.SpecialCells(xlCellTypeLastCell).Row - Rng1.Row
For i = 1 to j
If Rng1.Value = Cells(Rng1.Row + i, 1).Value Then
Set Rng2 = Cells(Rng1.Row + i, 1)
End If
Next
If Rng2 = Cells(1, 1) Then
MsgBox "There is no match"
Exit Sub
End if
Set Rng3 = Application.InputBox("Please select last date for returning", Type:=8)
For i=0 to abs(Rng1.Column - Rng3.Column)
If Rng2.Offset(0, Rng1.Column + i).Value <> "" Then
NameRef = "Fail"
MsgBox "Not all cells are empty in the destination row! _
Please start again.", vbCritical + vbOKOnly, "Cell Allocation Error"
End If
Next
If NameRef <>"Fail" Then
For i=0 to abs(Rng1.Column - Rng3.Column)
Cells(Rng2.Row, Rng1.Column + i).Value = _
Cells(Rng1.Row, Rng1.Column + i).Value
Cells(Rng1.Row, Rng1.Column + i).Value = ""
Next
End If
...
error handler
...
End Sub
Just check on the index "i" that it is working properly, maybe it is one unit short or long. It is difficult to reproduce your sheet to test it.
Hope it helps!

VBA Lastrow to not include certain values

I made this macro (and it works!) but I want to expand on it. Some of the data in the "Data" sheet is irrelevant and I don't want to autofill those rows in the "Databehandling" sheet.
I want to change the LastRow definition. Column G in my data-sheet contains a lot of dates and times (ex. 2016-09-26 09:42:56.290) and the data connected with the last date (2016-09-26) messes with my analysis (a lot of null-values because there's no data as-of-yet). Since I have to update this workbook regularly, I can't just say exclude 2016-09-26. The macro has to look at the date at the very bottom of the data-sheet and move the selection up so those dates aren't included in the selection.
So how can I do that?
Sub Kviklevering_Drag_Down()
On Error GoTo errHandler
Application.ScreenUpdating = False
With ActiveWorkbook
Lastrow = ActiveWorkbook.Sheets("Data").UsedRange.Rows.Count
Sheets("Databehandling").Activate
Range("A2:V2").Select
Selection.AutoFill Destination:=Range("A2:V" & Lastrow), Type:=xlFillDefault
End With
Sheets("Databehandling").Visible = False
Sheets("Data").Activate
Application.ScreenUpdating = True
errHandler:
Application.ScreenUpdating = True
End Sub
I've updated your code. Removed looking at the ActiveBook, activating sheets and moved the error handler outside the main procedure (after the Exit Sub, but before the End Sub).
Sub Kviklevering_Drag_Down()
Dim CountOfMaxDate As Long
Dim rLastCell As Range
Dim rCountRange As Range
Dim dMaxDate As Double
'Are you sure it's always the ActiveWorkbook?
'May be better to use ThisWorkbook which is always the file with this code in,
'or a specific named workbook.
'With ActiveWorkbook
On Error GoTo ErrorHandler
With ThisWorkbook
With Worksheets("Data")
'Find last cell in column G (column 7).
Set rLastCell = .Cells(.Rows.Count, 7).End(xlUp)
If rLastCell.Row = 1 Then
Err.Raise vbObjectError + 1000, , "Last Cell is row 1"
End If
Set rCountRange = .Range(.Cells(1, 7), rLastCell)
'Get the value of the last date.
dMaxDate = Int(rLastCell)
'Count the last date.
CountOfMaxDate = WorksheetFunction.CountIfs(rCountRange, ">=" & dMaxDate, rCountRange, "<" & dMaxDate + 1)
End With
'No need to active this sheet - can leave it hidden if you want.
With Worksheets("Databehandling")
.Range("A2:V2").AutoFill Destination:=.Range("A2:V" & rLastCell.Row - CountOfMaxDate), Type:=xlFillDefault
End With
End With
FastExit:
'Tidy up before exiting procedure.
Exit Sub
On Error GoTo 0
Exit Sub
ErrorHandler:
Select Case Err.Number
Case -2147220504 'Last Cell is row 1
'Handle error.
'Possible things to do after error handled:
'Resume Next
'Resume
'Resume FastExit
Case Else
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure Kviklevering_Drag_Down."
End Select
End Sub

vba#excel_highlight the empty cells

I'm creating an excel file with column A to H are mandatory cells.
This excel file will be passing around for input.
So, I would like to highlight the empty cells as a reminder.
I have written the following code...
Sub Highlight_Cell()
Dim Rng As Range
For Each Rng In Range("A2:H20")
If Rng.Value = "" Then
Rng.Interior.ColorIndex = 6 ‘yellow
Else
Rng.Interior.ColorIndex = 0 'blank
End If
Next Rng
MsgBox "Please fill in all mandatory fields highlighted in yellow."
End Sub
However, I would like to set the range from A2 to the last row that contains data within column A to H.
Also, display the message box only when empty cell exist.
Could you please advise how should I amend?
Million Thanks!!!
This is a VBA solution that prevents the user from saving until the desired range is filled (acknowledging Gserg's comment that that the last row is one that has at least one cell entered)
In the second portion you can either add your sheet index directly, Set ws = Sheets(x) for position x, or Set ws = Sheets("YourSheet") for a specific sheet name
The code will only highlight truly blank cells within A to H of this sheet till the last entered cell (using SpecialCells as a shortcut). Any such cells will be selected by the code on exit
Put this code in the ThisWorkbook module (so it fires whenever the user tries to close the file)
Private Sub Workbook_BeforeClose(Cancel As Boolean)
bCheck = False
Call CheckCode
If bCheck Then Cancel = True
End Sub
Put this code in a standard module
Public bCheck As Boolean
Sub CheckCode()
Dim ws As Worksheet
Dim rng1 As Range
Dim rng2 As Range
bCheck = False
'works on sheet 1, change as needed
Set ws = Sheets(1)
Set rng1 = ws.Columns("A:H").Find("*", ws.[a1], xlValues, xlWhole, xlByRows)
If rng1 Is Nothing Then
MsgBox "No Cells in columns A:H on " & ws.Name & " file will now close", vbCritical
Exit Sub
End If
Set rng2 = ws.Range(ws.[a1], ws.Cells(rng1.Row, "H"))
On Error Resume Next
Set rng2 = rng2.SpecialCells(xlBlanks)
On Error GoTo 0
If rng2 Is Nothing Then Exit Sub
bCheck = True
rng2.Interior.Color = vbYellow
MsgBox "Please fill in all mandatory fields on " & ws.Name & " highlighted in yellow", vbCritical, "Save Cancelled!"
Application.Goto rng2.Cells(1)
End Sub

Resources