Limit macro to set a range for textbox - excel

I am trying to link a range of cells to a text box, the only problem is if I edit the text box, it will write in any cell. I want to limit that ability to a specific range ("C4 to C11"). Here is my code:
Dim PreviousCell As Range
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Column = 3 Then ActiveSheet.TextBox1.Text = Target
If Not PreviousCell Is Nothing Then
Debug.Print PreviousCell.Address
End If
Set PreviousCell = Target ' This needs to be the last line of code.
End Sub
Private Sub TextBox1_Change()
ActiveCell.Value = TextBox1
End Sub

Private Sub TextBox1_Change()
If ActiveCell.Column = 3 Then ActiveCell.Value = TextBox1
End Sub

Related

Preventing Rows from being hidden based on cells not empty

I am needing to prevent a range of rows from being hidden if any of the rows have text in cells in D column.
Private Sub Worksheet_Change(ByVal Target As Range)
Set rRng = Sheet1.Range("D35, D36, D37, D38, D39, D40")
If Target.Row >= 34 And Target.Row <= 40 Then
If IsEmpty("rRng.value") Then
Range("D35:D40").EntireRow.Hidden = False
Else: Range("D35:D40").EntireRow.Hidden = (Range("D34").Value = "")
End If
End If
End Sub
You might need to trigger your hide/unhide from the calculate event too so that any formulas/vba that changes the values also triggers and update. (Im not sure what the intended result is, so the code below isn't a dropin replacement)
Private Sub Worksheet_Calculate()
HideRows
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
HideRows
End Sub
Public Sub HideRows()
Dim R As Range: Set R = Sheet1.Range("D35:D40")
If Excel.WorksheetFunction.CountA(R) > 0 Then
R.EntireRow.Hidden = False
Else
R.EntireRow.Hidden = True
End If
End Sub
Sub SetAValue()
Sheet1.Range("D35").Value = "show"
End Sub

UserForm to add from a selected cell from a TextBox value

I am trying to have a UserForm GUI so that we can add and subtract from inventory, I have got it so that I can select a worksheet and a row, but I am having trouble adding and subtracting part. Pretty new to VBA and I am not sure how to call that variable and modify it. Any help would be great!! Here is my code in the UserForm:
Option Explicit
Private Sub BTNadd_Click()
End Sub
Private Sub BTNDone_Click()
'This will save and close the GUI'
ThisWorkbook.Save
StgRmGUI.Hide
End Sub
Private Sub BTNrmv_Click()
End Sub
Private Sub ItmNmSlct_Change()
Dim actItm As String
End Sub
Private Sub ItmTypSlct_Change()
'This allows ItmTypSlct to show available wrkshts then will make item show in Item Name box'
With Worksheets(ItmTypSlct.Value)
ItmNmSlct.RowSource = Range(.Cells(2, 1), .Cells(Rows.Count, 1).End(xlUp)).Address(, , , True)
End With
End Sub
Private Sub NumBox_Change()
Dim NewVal As Integer
NewVal = Val(NumBox.Text)
If NewVal >= SpBtnARNum.Min And _
NewVal <= SpBtnARNum.Max Then _
SpBtnARNum.Value = NewVal
End Sub
Private Sub SpBtnARNum_Change()
NumBox.Text = SpBtnARNum.Value
End Sub
Private Sub UserForm_Click()
End Sub
Private Sub UserForm_Initialize()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
If ws.Visible = xlSheetVisible Then
ItmTypSlct.AddItem ws.Name
End If
Next ws
End Sub
An simple example of updating the column B value by the amount in NumBox
Private Sub BTNadd_Click()
Dim r As Long, cell As Range
With ItmNmSlct
r = .ListIndex
If r < 0 Then Exit Sub
' select quatity cell and increment value
Set cell = Range(.RowSource).Cells(r + 1, 2)
cell.Value = cell.Value + NumBox.Value
End With
End Sub

This routine does not work in protect mode

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim rg As Range
Set rg = Intersect(Target, Range("A1:J10"))
If Not rg Is Nothing And Range("V7") = "YES" Then
[RowNo] = ActiveCell.Row
[ColNo] = ActiveCell.Column
End If
End Sub
…
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("V7")) Is Nothing Then
If Target = "NO" Then [AK1:AL1] = 0
End If
End Sub
The above SelectionChange does not work when the sheet is in protect mode. Is there any way to correct this. In protect mode it hangs up on the line that says [RowNo] = ActiveCell.Row. This works correctly when sheet is unprotected.
Like this:
'...
Me.Unprotect 'in a sheet module Me=the sheet
[RowNo] = ActiveCell.Row
[ColNo] = ActiveCell.Column
Me.Protect
'...

Protect cell depending on other cell's value

I have an Excel spreadsheet where I want to protect cells in column I if the respective cell of column H <> "yes".
I found a code but it will protect all the cells of column I.
Option explicit
Sub unprotected
Me.unprotect password:= "abc"
End sub
Sub protect
Me.protect userinterfaceonly:= true ,password:= "abc"
End sub
Private Sub Worksheet_change(ByVal Target As Range)
Dim Crow as Long
Call Unprotected
xrow = Target.Row
If not (intersect(Target, range("H3:H1000")) is nothing then
Cells(xrow, "I").locked = (Ucase(trim(cells(xrow, "H").value))<>"yes")
End if
Call protect
End sub
Try this:
Option Explicit
Const PW As String = "abc" '<< use a constant for fixed/shared values
Private Sub Worksheet_change(ByVal Target As Range)
Dim rng As Range, c As Range
'find changed cells in range of interest
Set rng = Application.Intersect(Target, Me.Range("H3:H1000"))
If Not rng Is Nothing Then
UnprotectMe
'process each cell
For Each c In rng.Cells
Me.Cells.Cells(c.Row, "I").Locked = _
(UCase(Trim(Me.Cells(c.Row, "H").Value)) <> "YES")
Next c
ProtectMe
End If
End Sub
Sub UnprotectMe()
Me.Unprotect Password:=PW
End Sub
Sub ProtectMe()
Me.protect userinterfaceonly:=True, Password:=PW
End Sub

How can I spread a sub to a multiple range of cells?

The purpose of this code is to update the date in a cell as a certain cell's contents are changed.
Since this was originally coded inside a sub, I now need to expand this code to a range of multiple cells. Ie. At this moment, the code only takes cell D4 and updates cell L4, I want to be able to drag this function down so it can reach a multiple range of cells; take D5 and update L5 etc.
Here's my code as the sub:
Dim oldValue
Public Sub Worksheet_SelectionChange(ByVal Target As Range)
oldValue = Target.Worksheet.Range("D4").Value
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Worksheet.Range("D4")) Is Nothing Then
If oldValue <> Target.Worksheet.Range("D4").Value Then
Target.Worksheet.Range("L4").Value = Date
End If
End If
End Sub
The problem here, is that I don't know how to properly expand my code to match a further selection of cells. Here's my attempt:
Dim oldValue
Public Sub Worksheet_SelectionChange(ByVal Target As Range)
oldValue = Target.Worksheet.Range("D4", "D21").Value
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Target.Worksheet.Range("D4", "D21")) Is Nothing Then
If oldValue <> Target.Worksheet.Range("D4", "D21").Value Then
Target.Worksheet.Range("L4", "L21").Value = Date
End If
End If
End Sub
EDIT: The sub I have written only applies to one cell, I am trying to work out a way to have it spread out to a certain selection of cells. Ie. D4:D12 which updates the date in L4:L12 accordingly.
If anyone could help me, that would be greatly appreciated.
Try the following code:
Dim oldValue()
Public Sub Worksheet_SelectionChange(ByVal Target As Range)
oldValue = Me.Range("D4:D12").Value
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("D4:D12")) Is Nothing Then
Application.EnableEvents = False
Dim c As Range
For Each c In Intersect(Target, Me.Range("D4:D12"))
'Check value against what is stored in "oldValue" (row 4 is in position 1, row 5 in position 2, etc)
If oldValue(c.Row - 3, 1) <> c.Value Then
'Update value in column L (8 columns to the right of column D)
c.Offset(0, 8).Value = Date 'or possibly "= Now()" if you need the time of day that the cell was updated
End If
Next
Application.EnableEvents = True
End If
End Sub
Set up a hidden sheet to hold the old values.
Sub SetupMirrorValues()
With Worksheets.Add
.Name = "MirrorValues"
.visibilty = xlSheetVeryHidden
.Range("D4:D10,D12,D14:D20") = Worksheets("Sheet1").Range("D4:D10,D12,D14:D20")
End With
End Sub
In the Worksheet_Change event handler, you would check the Target cells that intersect with the range you want to monitor. If there are differences then you update the timestamp and the cell on the hidden sheet that corresponds to the changed cell.
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
Application.ScreenUpdating = False
Dim cell As Range, DRange As Range
Set DRange = Range("D4:D10,D12,D14:D20")
If Not Intersect(DRange, Target) Is Nothing Then
For Each cell In Intersect(DRange, Target)
If cell.Value <> Worksheets("MirrorValues").Range(cell.Address) Then
cell.EntireRow.Cells(1, "L").Value = Now
Worksheets("MirrorValues").Range(cell.Address) = cell.Value
End If
Next
End If
Application.EnableEvents = True
Application.ScreenUpdating = False
End Sub

Resources