Excel | autostart macro on cell value change | cause crash - vba

first of all I'm not a VBA programmer but typically an end-user who uses snippets of code that I gather in forums like this in his spreadsheets, trying to understand what the code does. Code for which I thank you all!
My objective:
I have a spreadsheet that is basically an input-form for users.
Based on their input and selections via dropdown my intention is to guide them through the form by hiding & unhiding rows with input fields, presenting the users with the relevant questions.
On each row I have created an IF-formula that creates a 1 or 0 based on previous provided input
1 -> unhide the row , 0 -> hide the row.
So I'm looking for a macro that runs with every sheet calculation and hides or unhides the next rows as needed.
These formulas are in range I3:I70 on top of that I created a summary field in I2 =sum(I3:I70) so i thought I can either check changes in the range I3:I70 or changes on cell I2 to trigger the macro. [Neither solution fixed my problem]
I've tried several code examples discribed on the forums and I've tested the macros that checks for change in the range or the cell individually.
As long as I call a test macro with a MsgBox it works fine.
Also the macro that hides or unhides runs fine when I call it manually.
My problem:
When I let the 'auto'-macro call the 'hide'-macro, Excel simply crashes; no warnings, nothing --> just crash.
My code:
Private Sub Worksheet_Calculate()
Dim Xrg As Range
Set Xrg = Range("H3:H70")
If Not Intersect(Xrg, Range("H3:H70")) Is Nothing Then
Macro1
End If
End Sub
Sub Sample()
MsgBox "Yes"
End Sub
Sub Macro1()
Dim cell As Range
For Each cell In Range("H3:H70")
If Not IsEmpty(cell) Then
If cell.Value = 0 Then
cell.EntireRow.Hidden = True
End If
If cell.Value = 1 Then
cell.EntireRow.Hidden = False
End If
End If
Next
End Sub
Thanks for any suggestions and tips in advance.
JeWe

Never give up searching :-) I gave it a last search and found some code on the microsfof dot com site that seems to work.
Don't ask me the details but this seems to do what i'm looking for
Private Sub Worksheet_Calculate()
Dim LastRow As Long, c As Range
Application.EnableEvents = False
On Error Resume Next
For Each c In Range("H3:H70")
If c.Value = 0 Then
c.EntireRow.Hidden = True
ElseIf c.Value = 1 Then
c.EntireRow.Hidden = False
End If
Next
On Error GoTo 0
Application.EnableEvents = True
End Sub
It's late on my end of the world, going to sleep. Will update tomorrow.
Txs JeWe

Related

excel hide rows with error values based on dropdown change

I would like to hide rows in column B9-B40 when Index/Match formula returns "N/A" , now I managed to get it done in VBA when the table is static but I have a dynamic table based on drop-down selection which means the number of N/As returned can be different for each time drop-down selection changes.
Here is what I have right now which hides the rows with N/A based on current drop-down selection, my dropdowns are in C2,C3 and C4. But it doesn't takes any further change in the dropdown into consideration afterwards. I am not very competent with the VBA so any help would be great.
Thanks.
Option Explicit
Sub hide_if_error()
Dim MyCell As Range, Rng As Range
Set Rng = Range("B9:B40")
For Each MyCell In Rng
If IsError(MyCell) Then
MyCell.EntireRow.Hidden = True
End If
Next MyCell
End Sub
You can do
Range("B9:B40").SpecialCells(xlCellTypeFormulas, xlErrors).EntireRow.Hidden = True
You will need a test in advance that errors are present though.
That might look like:
Option Explicit
Public Sub hide_if_error()
With ThisWorkbook.Worksheets("Sheet4")
.Range("B9:B40").EntireRow.Hidden = False
If Evaluate("=SUM(IF(ISERROR(" & .Range("B9:B40").Address & "),1))") > 0 Then '<==check if any errors present
.Range("B9:B40").SpecialCells(xlCellTypeFormulas, xlErrors).EntireRow.Hidden = True
End If
End With
End Sub
If necessary, you could link the above to a worksheet change or dropdown change event so it is fired each time there is an update using the dropdown(s)
For example:
If you data validation was in C2:C4 you would put in the code pane for the sheet the following event code:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo ErrHand
If Not Intersect(Target, Range("C2:C4")) Is Nothing Then
Application.EnableEvents = False
hide_if_error
End If
ErrHand:
Application.EnableEvents = True
End Sub
Note:
The worksheet event code goes in the code pane associate with sheet 4:
The other code goes in a standard module (module 1 here):
Example run:

Excel VBA code to select all cells with data sometimes working

I once built a VBA button to automatically lock all cells with data in them. And it was working perfectly. Now I wanted to copy that button to another worksheet. So I created another button, copy and pasted the whole VBA over, then edited the worksheet names and range. And, it's only working like 5% of the time, the rest of the time, I'm getting an "Run-Time error '1004': No cells were found." I've tried a few fixed, changing Sheets to Worksheets, or adding a ", 23" to the specialcells argument. However, nothing is working right now. When I try stepping in, it sometimes say both rng and lckrng as empty, and sometimes only show lockrng as empty and not show rng at all. Problem is this used to be a working code, and now, it still works around 5% of time. Any idea why? Thank you very much!
Private Sub CommandButton1_Click()
Dim rng As Range
Dim lockrng As Range
Sheets("Uploading Checklist (M)").Unprotect Password:="signature"
Set rng = Range("A1:M14")
'Selecting hardcoded data and formulas
Set lockrng = Union(rng.SpecialCells(xlCellTypeConstants), rng.SpecialCells(xlCellTypeFormulas))
lockrng.Locked = True
Sheets("Uploading Checklist (M)").Protect Password:="signature"
End Sub
Maybe this is too simplistic, but it seems to do what you want. The animated .gif shows it working to "lock all cells with data in them". (I made the second button just for convenience). If nothing else it might be good to start from something like this that works and modify to suit your needs.
Dim cell As Range, sh As Worksheet
Sub Button4_Click()
Set sh = Worksheets("Sheet1")
sh.Unprotect Password:="s"
For Each cell In sh.UsedRange
If cell <> "" Then cell.Locked = True Else cell.Locked = False
Next
sh.Protect Password:="s"
End Sub
Sub Button5_Click()
Set sh = Worksheets("Sheet1")
sh.Unprotect Password:="s"
End Sub
The Union you are attempting will not work if either of the parameters is Nothing (i.e. you either have no constants in the range, or you have no formulas in the range).
Prior to doing the Union, you should check the parameters aren't Nothing but, once you start changing your code to do that, it would be just as simple to do the locking in two parts - so I recommend you rewrite the code as follows:
Private Sub CommandButton1_Click()
With Sheets("Uploading Checklist (M)")
.Unprotect Password:="signature"
With .Range("A1:M14")
'Lock any constants
If Not .SpecialCells(xlCellTypeConstants) Is Nothing Then
.SpecialCells(xlCellTypeConstants).Locked = True
End If
'Lock any formulas
If Not .SpecialCells(xlCellTypeFormulas) Is Nothing Then
.SpecialCells(xlCellTypeFormulas).Locked = True
End If
End With
.Protect Password:="signature"
End With
End Sub

Program excel to return a specific value

I have a spreadsheet that is going to be used in a survey.
How can I make the cells only to return "x" regardless of what the survey taker type in.
For instance, if I write a "w" in the cell, it should turn into an "x".
I have come to a point where I think there is an option when I protect the workbook or sheet. Because I can tell from another spreadsheet (which has this function) that it only works if the workbook is protected.
I tried to google it, but it seems as if I don't know the right keywords to find the answer.
Also, I have found a set of Vba code that I fiddle with, but I'm not sure this is correct. I don't want to attach the code as I don't want to confuse any response here.
Thank you for any help provided.
Put this code in the worksheet module and test it out, when you change a cell in column A (1) it will activate,
Where is the worksheet Module?
Copy and paste the code ,
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Intersect(Target, Range("A1,B1,C1,A4,B4,C4")) Is Nothing Then Exit Sub
Application.EnableEvents = 0
If Target <> "" Then Target = "X"
Application.EnableEvents = 1
End Sub
This should work for you (just change the range to the one you need) :
Option Explicit
Sub worksheet_Change(ByVal Target As Range)
On Error GoTo errorbutler 'error handler - important to have this in case your macro does a booboo
Application.Calculation = xlCalculationManual 'turn off automatic calculation to speed up the macro
Application.EnableEvents = False 'turn off events in order to prevent an endless loop
Dim LR, cell As Range 'Declare your variables
Set LR = Range("A1:b3") ' Select range of cells this macro would apply to
For Each cell In Target 'Loops through the cells that user have changed
If Union(cell, LR).Address = LR.Address Then 'Checks if the changed cell is part of your range
cell.Value="x" 'changes the value of that cell to x
End if
Next cell
Errorexit: 'part of error handling procedure
Application.EnableEvents = True 'Turn autocalc back on
Application.Calculation = xlCalculationAutomatic 'turn events back on
Exit Sub
Errorbutler: 'error handling procedure
Debug.Print Err.Number & vbNewLine & Err.Description
Resume Errorexit
End Sub
Oh yes, and this code should be put into the worksheet module - the same way as Dave has shown you

How to use VBA to execute a macro based on an IF statement?

I want to run an Excel VBA code (all it will do is delete specific cells within the same row and I've turned on relative reference so that I can apply the Excel VBA code to all rows, if there's the appropriate "X") based on whether there is an X in a certain cell.
Here's what I've tried so far (the Excel VBA code is just called "Biology"):
If Range("C22").Value = "X" Then
Call macro_Biology
End If
I should add that I'm writing this under VBA section "GetATPLabel". Like I said, total noob, but I think I'm close, so any help is appreciated.
It sounds as if it is important that the Biology (or macro_Biology) macro needs to know which row it is supposed to work on. You can pass this information across to it with a parameter. Example:
Sub start_with_this()
Dim rw As Long, lr As Long
With ActiveSheet
lr = .Cells(Rows.Count, "C").End(xlUp).Row
For rw = 2 To lr
If UCase(.Cells(rw, "C").Value) = "X" Then
Call macro_Biology(rw)
End If
Next rw
End With
End Sub
Sub macro_Biology(r As Long)
' r is the row that was passed in.
' do something with r
End Sub
After initially starting the start_with_this macro, it goes through each cell in column C from row 2 to the last row with anything in it. If it finds an X or an x (case-sensitivity is removed by forcing the cell value to upper case before comparing) then it calls the second macro, macro_Biology and tells it what row to deal with.
Lets assume that Biology() is a sub in a standard module:
Sub Biology()
MsgBox "study biology!"
End Sub
To call this as you want, run:
Sub TestIt()
If Range("C22").Value = "X" Then
Call Biology
End If
End Sub
To call Biology() automatically if the user types an X in cell C22, Insert the following event macro in the worksheet code area:
Private Sub Worksheet_Change(ByVal Target As Range)
Set intrs = Intersect(Target, Range("C22"))
If Not intrs Is Nothing Then
If intrs.Value = "X" Then
Application.EnableEvents = False
Call Biology
Application.EnableEvents = True
End If
End If
End Sub
To call Biology() automatically if a formula gives an X in cell C22, Insert the following event macro in the worksheet code area:
Private Sub Worksheet_Calculate()
If Range("C22").Value = "X" Then
Application.EnableEvents = False
Call Biology
Application.EnableEvents = True
End If
End Sub

Pop up a message in vba

I am working on a file which in one sheet lets call it summary, I have formula that calculate the values which Ienter manually in other sheets, so I want to have an vba code to notify me by pop up message that the calculation result in summary sheet is <=0 when doing data entry in other sheets.
I have found below code which works fine with only one cell but if I want to extend it to other cells in the same row results in error. Suppose I want to extend it to B9:CZ9.
Private Sub Worksheet_Calculate()
If Me.Range("B9").Value <= 0 Then _
MsgBox "Leave is finished!"
End Sub
Possible background:
Private Sub Worksheet_Calculate()
With Me.Range("B9:CZ9")
If Application.CountIf(.Cells, "<=0") = .Cells.Count Then _
MsgBox "Leave is finished!"
End With
End Sub
Private Sub Worksheet_Calculate()
Dim RNG As Range
Set RNG = Selection
For Each c In RNG
If c.Value <= 0 Then
MsgBox "Leave is finished!"
End If
Next c
End Sub
If I understood you correctly, maybe this code helps you (you have to put this code to the source of the correct worksheet you want to work this code on):
Private Sub Worksheet_Calculate()
Dim leave As Boolean: leave = False
For Each c In Me.Range("B9:CZ9").Cells
If c.Value <= 0 Then: leave = True
Next
If leave Then: MsgBox "Leave is finished!"
End Sub
This code works when something is calculated in a cell, for example when you type =0 into any of them, and don't give you lots of messageboxes.
If you want this to work when anything changes, use Private Sub Worksheet_Change(ByVal Target As Range)
Remember that extension xlsx cannot contain VBA codes. Therefore after implementing the code to the worksheet you want this code works on, you have to save it as macro-enabled workbook.