Automatically updating a userform label - vba

I'm new to VBA and programming in general, so bear with me. I have so far 6 labels, and a simple useform where one enters a value corresponding to each label. However, the label name can change (say if new labels are added) and I wanted a way to automatically change the label name. This is what I have so far:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Update_invest.Invest1.Caption = Sheet1.Range("A12").Value
Update_invest.Invest2.Caption = Sheet1.Range("A13").Value
Update_invest.Invest3.Caption = Sheet1.Range("A14").Value
Update_invest.Invest4.Caption = Sheet1.Range("A15").Value
Update_invest.Invest5.Caption = Sheet1.Range("A16").Value
Update_invest.Invest6.Caption = Sheet1.Range("A17").Value
End Sub
Now this works: if I change a label it will update the userform. However, if I just open the new worksheet and don't click on say cell A12, it will not update the userform and will leave the label name as it's default name. How do I make it actually save the label name, so that if a user opens the workbook the userform will already have the current cell value (without first having to click on the cell for the userform to update)?
I have this code currently on sheet1.

Solution 1
You can put your code in Worksheet_Activate which is run when the user select the sheet or in Workbook_Open which is run when the user open the workbook. Currently, your are using Worksheet_SelectionChange which is only run when the user change the selection, hence the need to click on another cell.
NOTE : if you chose to use Workbook_Open, you will need to put the sub in the ThisWorkbook file and not in the worksheet itself.
Solution 2
If you instead want to make the changes permanant and not have code to always update it, you will need to go through the designer
Here is an exemple
Sub exa1()
Dim i As Long, n As Long
n = 12
With ThisWorkbook.VBProject.VBComponents("Update_invest").Designer
For i = 1 To .Controls.Count
If TypeName(.Controls(i - 1)) = "Label" Then
.Controls(i - 1).Caption = Sheet1.Cells(n, 1).Value
n = n + 1
End If
Next i
End With
End Sub
source

Related

Adding Command Button allowing user to view hidden sheet

I am new to using Macros/VB in excel and in need of some help (in the simplest way you can instruct me)
I have a workbook with two sheets. I have already created a form on sheet 1 which will allow users to enter data which then is populated within a hidden sheet (sheet2).
I would like to add a button on sheet 1 for the user to view the hidden "list data" they have entered in sheet 2 but they cannot be able to edit the data - only view it.
Any help would be greatly appreciated.
Insert a shape (I prefer this over an ActiveX control) on the sheet with your form. I named the shape "Show data" and gave that same caption to the button. Now add the following code to a standard code module (one which VBE names like "Module1").
Option Explicit
Sub ShowData_Click()
' 25 Jul 2017
With ThisWorkbook.Worksheets("Jeanette")
.Visible = xlSheetVisible
.Activate
End With
End Sub
Change the name of the worksheet with the data to the name you have given that sheet in your project. Then right-click on the button (shape) and select "Assign macro". Assign the "ShowData_Click" macro. Now, when you click the button the hidden sheet will become visible and be activated.
In the code sheet for the data sheet (which is normally hidden), add the following to procedures.
Option Explicit
Dim ThisSheet As String
Private Sub Worksheet_Activate()
' 25 Jul 2017
ThisSheet = ActiveSheet.Name
End Sub
Private Sub Worksheet_Deactivate()
' 25 Jul 2017
On Error Resume Next
Worksheets(ThisSheet).Visible = xlSheetVeryHidden
End Sub
The first one will run whenever the sheet is activated which happens when the new button is pressed. It will remember the name of the sheet. This is so that you don't need to hard-code the name.
The second procedure will run whenever you activate another sheet in the workbook. It will hide the sheet again. So, you show the sheet by pressing the button and hide the sheet by selecting another sheet.
I'm not a friend of Excel's protection. So, I suggest another way to prevent users from modifying the data. Here is the code. Install it on the same code sheet where you already have the Activate and Deactivate procedures.
Private Sub Worksheet_Change(ByVal Target As Range)
' 25 Jul 2017
Static ShowMsg As Integer
With Application
.EnableEvents = False
.Undo
ShowMsg = ShowMsg + 1
If (ShowMsg Mod 3) = 1 Then
MsgBox "Data in this sheet may not be modified." & vbCr & _
"Your changes have been removed.", _
vbInformation, "Invalid action"
End If
.EnableEvents = True
End With
End Sub
This code will undo any change the user makes. The user will receive a message to this effect each third time he/she tries to modify something.

Command Button () should be clicked only when certain sheet available

I am getting data on daily basis. For that I use different command buttons to filer data and gather data from different sheets. Already kept made around 25 command buttons on first sheet. My issue is e.g. command button say 20 should not be work or should not be click until unless sheet no. 20 available. Currently I am using
Dim j As Integer, k As Integer
j = Worksheets.Count
For k = 20 To 20
With Worksheets(k)
Sometimes by mistake I click on command button which particular sheet not available and code does not generate any data.
Could you do something like below?
Obviously you need to replace the "20" with whatever your sheet name is and
and you will put this code in your click handler
Dim isWorlsheetAvailable
isWorlsheetAvailable = False
For i = 1 To ActiveWorkbook.Worksheets.Count
If ActiveWorkbook.Worksheets(i).Name = "20" Then
isWorlsheetAvailable = True
End If
Next i
If Not isWorlsheetAvailable Then
MsgBox ("sdffd")
Exit Sub
End If
Do your work here......

Conditional formatting excel textbox

What is the best way to change the font color of a single textbox based on value of linked cell?
Textbox is located on sheet1 when recording macro it recognizes textbox as ActiveSheet.Shapes.Range(Array("TextBox 1")).Select
I have inserted an image on sheet1, then I inserted textbox's from the insert toolbar. All the textbox's are linked to data on the "stylist" sheet. This sheet gets updated with a macro when the workbook is opened. I'm trying to get the textbox fonts to be red or green based on comparing the value of the linked cell to another cell on the stylist sheet.
enter image description here
Please try this..
' replace Text with your text box name
ActiveSheet.Text.Object.ForeColor = RGB(0, 255, 0)
With the code you provided and described as having a linked cell, one would assume you are referring to a TextBox from the ActiveX toolbar.
The code for that textbox is located in the Worksheet module. Right click on the sheet tab and select View code to open that module.
If your Linked cell is A1 then we could use a Worksheet_Change event to trigger the code when you change A1.
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Target.Address <> "$A$1" Then Exit Sub
Dim x
x = IIf(Target <= 0, vbRed, vbGreen)
Me.TextBox1.ForeColor = x
End Sub
You can also use the TextBox1_Change event, this would trigger when the textbox changed.
Private Sub TextBox1_Change()
Dim x
x = IIf(TextBox1.Value <= 0, vbRed, vbGreen)
Me.TextBox1.ForeColor = x
End Sub
You did not indicate what the conditions were so I made up my own.This example uses,
if <=0 then red, else green
The results would be

Is there a way to have a scrollable list that is editable?

Following this video I have a spreadsheet that has a "Edit History" box on it that scrolls up and down. It uses a forms control scroll box and a list on a secondary sheet to create a scrollable list. The problem with this is that you cannot then edit the information in the scroll box (you must edit it on the secondary sheet).
I have VBA that automatically enters the person's name into the scrollbox when they edit any part of the sheet, and then enters "Note:" below that. I want the person to be able to edit the "Note:" box so that they can enter the reason they are editing the sheet:
John Smith and James Appleseed are previous users of this sheet. When Wayne Smith comes in to edit the sheet, as soon as he makes a change, it adds "Wayne Smith" and "Note:" to the sheet. (I already have this part working using VBA).
Because of the way that the scroll able list is implemented, it is actually all just formulas within this edit history box. If I double click "Note:" to try and edit it, this is what appears:
But what I want to happen is the ability to edit the "Note:" box (without having to switch to the secondary sheet where the list is actually stored). Essentially I want to make a scroll able text box that is also directly editable, and works with VBA.
Is there any way to do this?
I put together a working example of how to do this.
You can download the workbook here.
This method uses two sheets in a workbook... Sheet1 for the listbox and listboxdata for the data. Sheet1 can be called anything you like.
It would probably be wise to hide the listboxdata sheet.
On Sheet1 you need a Forms Control scrollbar. Use the Name Box to rename it: ScrollBar1. Assign to it the Scroll() procedure.
All of the code for this app should be placed in the Sheet1 code module:
Option Explicit
Private Const LISTBOX_SCROLLBAR = "scrollbar1"
Private Const LISTBOX_DATASHEET = "listboxdata"
Private Const LISTBOX_DATAHEADR = "a1"
Private Const LISTBOX_SCROLLMAX = 50
Private Const LISTBOX_SCROLLMIN = 1
Private Sub Scroll()
Dim ListBoxRows&, n&, ndx&, v
On Error Resume Next
With Shapes(LISTBOX_SCROLLBAR)
SetProps ndx
ListBoxRows = .BottomRightCell.Row - .TopLeftCell.Row
v = ThisWorkbook.Sheets(LISTBOX_DATASHEET).Range(LISTBOX_DATAHEADR).Resize(ListBoxRows).Offset(ndx)
Application.EnableEvents = False
.TopLeftCell(, 0).Resize(ListBoxRows) = v
End With
Application.EnableEvents = True
End Sub
Private Sub Update(Target As Range)
With Shapes(LISTBOX_SCROLLBAR)
If Target.Column = .TopLeftCell(, 0).Column Then
If Target.Row >= .TopLeftCell.Row And Target.Row <= .BottomRightCell.Row Then
If Target.Count = 1 Then
ThisWorkbook.Sheets(LISTBOX_DATASHEET).Range(LISTBOX_DATAHEADR).Offset(.ControlFormat.Value + Target.Row - .TopLeftCell.Row) = Target
Else
Scroll
End If
End If
End If
End With
End Sub
Private Sub SetProps(Optional ndx&)
With Shapes(LISTBOX_SCROLLBAR).ControlFormat
.Min = LISTBOX_SCROLLMIN
.Max = LISTBOX_SCROLLMAX
ndx = .Value
End With
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Update Target
End Sub
Private Sub Worksheet_Activate()
SetProps
End Sub
That's it.
No formulas required in the listbox and any changes made to the cells in the listbox will be written to the source data and kept.

Looking for a new method to create 'check-in' and 'check-out' system

I am currently working on a database for a small building with a large number of HDDs and the system I have made so far works exactly as my employer desires it to.
My current problem is with some VBA coding using macros to sign in and sign out each hard drive, the hard drives have a row each with a 'check in' and 'check out' button at the end. At current moment the coding works for both of these buttons but I have to write out the code for every single button both 'check in' and 'check out'.
Is there a way to convert the location of the button into a string which would then add itself into the coding and I can put in some sort of array that will auto locate the output of each button for me?
The macro is a simple .Show statement.
My excel sheet is illustrated below. Most of the current cells are programmed with formulas as this system needs to be fairly automated for the less skilled computer users.
Edit:
After clicking the button my initials are added to the end of current time/date. This needs to happen for many buttons all results being in different cells.
My recommendation would be to avoid using a button, and instead override the SelectionChanged event handler for the worksheet. Change the buttons to formatted cells, which when clicked will perform the action you desire.
First, configure your UserForm to return a value. One way to do this is by placing the following code into the code-behind for the UserForm:
Public Property Get Initials() As String
Initials = txtInitials.Text
End Property
Public Property Let Initials(ByVal sInitials As String)
txtInitials.Text = sInitials
End Property
Private Sub btnOk_Click()
Me.Hide
End Sub
Next, add the following code to Sheet1:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim sInitials As String
Dim sDate As String
Dim sTime As String
Dim frmInitials As InitialsForm
If Target.Column = 13 Then
Set frmInitials = New InitialsForm
frmInitials.Show
sInitials = frmInitials.Initials
Unload frmInitials
sDate = Date
sTime = Time
Cells(Target.Row, 6).Value = sDate + " / " + sTime + " " + sInitials
End If
End Sub
When the user clicks on a cell in column 13 (M - "Check Out"), a userform will be displayed asking for the user's initials. Once they have entered them and pressed the OK button, the initials will be added to the end of the timestamp and inserted into column 6 (F) of the same row.