cell value to change when hiding/unhiding specific rows in excel? - excel

I am currently working with an excel sheet where I have grouped row 1-17 and have written a cell value in cell B18. I am wondering if there is a way to change the value in B18 when I click on the +/- sign when expanding/collapsing the rows.
For example: I want the cell value in B18 to be "Yes" when I click on the plus sign, and the value to be "No" when I click on the minus sign. Is there any way to do this?
Kinds regards,
Sandra

Hello and welcome to Stack Overflow!
In general, you should always provide some proof (code) of your previous attempts, not only it helps us to understand better what you're trying to achieve, but also because of core principle behind this website is to help people with their code, not to do the coding for them!
Either way, I'll go out of my way and make an exception, given this is your first question and what you're trying to achieve is fairly easy to do.
Though my answers depends on what exactly you're trying to achieve though as it's not clear from your intial question.
If all the rows (1:17) are hidden
Private Sub check_hidden_area()
If Rows("1:17").EntireRow.Hidden = True Then
Range("B18") = True
Else
Range("B18") = False
End If
End Sub
If at least 1 row in (1:17) is hidden:
Private Sub check_hidden_area()
Range("B18") = False
For i = 1 To 17
If Rows(i).EntireRow.Hidden = True Then
Range("B18") = True
Exit For
End If
Next i
End Sub
PS/Note: The procedures listed do work, but as of now they don't auto-trigger (start) unless you launch them manually. Unfortunately it is impossible to trigger the code on the "+/-" buttons.
Closest thing you can get to this being correct is to fire the macro on every worksheet change, this will however clog down the speed of your program and hog your CPU/Memory, especially if working with bigger data ranges
Private Sub Worksheet_Change (ByVal Target as Range)
'...
Call check_hidden_area
End Sub
Alternatively just create a button (or something..) and call the procedure on _Click trigger, eg.
Private Sub CommandButton1_Click
Call check_hidden_area
End Sub

Related

Excel VBA : cells change values depending on specific groups (expanded or collapsed)

I'd like to modify values on specific cells depending on a specific group if it's expanded or collapsed.
I found a way, but it's a manual way (image1 image2) (the macro needs to be launched on each run).
Is there a way to use a function (i.e. worksheet_change), so that will be on real time ?
P.S. Sorry for my bad English and be kind, I'm kinda new on VBA (first code).
Thank you.
Private Sub groups()
If Worksheets("Feuil1").Columns("F").ShowDetail = True Then
Range("K2:K7").Value = "YES"
Else
Range("K2:K7").Value = "NO"
End If
End Sub
Thank you Luuklag for your solution, but as I said in my comment, in your code I have to update manually the placeholder cell which is not what I'm looking for.
But, I found something where my cells get updated by expanding or collapsing my group. And for this, as you said, I need a placeholder cell that gets updated on each calculation.
I use the formula =NOW on cell A1, because it's always useful to know the time and date.
Here is the (combined) code, for those who are looking a solution :
Private Sub Worksheet_Calculate()
Application.EnableEvents = False
'Where F is the column having the group button
If Columns("F").ShowDetail = True Then
'This is where you choose the cells that are dependent to the group and attribute something
Range("G10:G19").Value = "YES"
Else
'Same here. It could be other cells too
Range("G10:G19").Value = "NO"
End If
Application.EnableEvents = True
End Sub
There is a simple solution to this. Every time you expand or collapse a group you trigger the worksheet_calculate event. This can be used to your advantage.
All you need is a placeholder cell, which you populate with a volatile function (a function that changes its value on each calculation). You can use =randbetween(1,10) or =NOW() for example.
You then have your worksheet change event to look for your placeholder cell, AA1 in this example.
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("AA1")) Is Nothing Then
Call groups
End If
End Sub

Setting Range.Value causes #VALUE! in Excel VBA, and also resubmitting a function causes all other functions to be resubmitted

I apologise for how trivial this must be for VBA developers, but I have done some digging and cannot fathom why the following code, when assigned to a cell and executed, results in #VALUE!
Function foo()
Range("A1:B3").Value = 10
End Function
The excel sheet:
I initially tried
ActiveSheet.Range("A1").Value = "abc"
but that didn't work either. What very simple thing am I doing wrong here?
Also, why, when I try to re-execute the function (using F2 and then Enter), does excel resubmit other functions that are in the same worksheet? This is truly maddening. I have hit F2 and Enter, so why would Excel think that I want to resubmit all other functions, and how can this be prevented?
Thanks very much.
Edit: You tried to use UDF for changing some fields and consistent about the use of some kind of event modification instead of firing your code from a button in your comments with #Mathieu Guindon. Since UDF fire the code only when some cells are recalculated, it is assumed that your requirement is to fire the code when some cells in the sheet get changed either manually or through some formula. The solutions offered below run the code when value of cell F1 change. You may please modify it according to your need.
Old Post: It is not a clean way but may be a called dirty workaround idea. Supposing you want to any change in cell F1 value to execute the code, may try
Public F1Val As Variant
Private Sub Worksheet_Activate()
F1Val = Range("F1").Value
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If F1Val <> Range("F1").Value Then
Range("A1:B3").Value = 10
F1Val = Range("F1").Value
End If
End Sub
Caution:Certainly it will backfire if cell F1 is linked with formula with the cells getting changed.
Alternately if only manual change of cell F1 is suffice for code to execute then may simply try
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("F1")) Is Nothing Then
Range("A1:B3").Value = 10
End If
End Sub

Message box appear based on different criteria

I have some complicated Excel formatting to do, but I have no idea where to begin.
There are few criteria that need to be met:
When there are cell values in F3 and H3, the time at cell N4 should automatically be the time in N3 plus three hours.
If system time is exceeds the value in N4, and the value in F4 and H4 is still empty, it will trigger a message or format highlighting to inform user that the time is over.
If there is new bath being created in column B, the time in column N will stop adding the time and just left blank for user to key in the new time.
For 1. & 3., you'd simply use an if formula:
=IF(AND(F3<>"",H3<>"",B3=B4),N3+3/24,"")
This is assuming the value in N3 is a time value, otherwise it gets a bit trickier - but hardly impossible.
Your problem statement no. 2 is somewhat trickier, I don't think you can it without VBA, and the code isn't entirely straightforward. However, I'll give it a go. In a similar-ish workbook, I have a line which moves forward to indicate when different tasks needs to be completed. To have the "line" move, I color in a column of cells using conditional formatting, comparing the column of cells to a timestamp I have in Y29. The code I use to update the timestamp is the following, it updates the cells every minute:
In a standard module
Option Explicit
Public setDate As Date
Public Const nameToIgnore = "OAA0006Monitor"
Sub UpdateTime()
If currentUser() = nameToIgnore Then
Else
setDate = Now() + TimeValue("00:01:00")
Application.OnTime setDate, "TimeUp"
End If
End Sub
Sub TimeUp()
If currentUser() = nameToIgnore Then
Else
ThisWorkbook.Worksheets("ArbPlan 2011 (5)").Range("Y29") = Time
UpdateTime
End If
End Sub
Sub KillOnTime()
If currentUser() = nameToIgnore Then
Else
On Error Resume Next
Application.OnTime setDate, "TimeUp", , False
On Error GoTo 0
End If
End Sub
In the ThisWorkbook-module
Option Explicit
Private Sub Workbook_Activate()
UpdateTime
End Sub
Private Sub Workbook_Deactivate()
KillOnTime
End Sub
I don't think this should be very hard to convert to the purpose you want it for, instead of using conditional formatting, you can even have the code do all the formatting for you! :)
Anyway, I hope this gives you a good starting point, feel free to comment if you feel anything is unclear, or if you have trouble understanding any of the logic of the code.

VBA macro to run based on the outcome of a cell

I want to be able to run macros based on the outcome of the cell, for example.
If A1 is 1111100 then run X macro If its 1000000 then run this macro etc. I have had a look at "Case Select" but my lack of knowledge in this matter makes me thing that might not be what I want.
Any ideas? :/
Thank you in advanced.
JB
you can combine the two types, and yes, a Case Select is the easiest to read and maintain.
Here's example code that runs different routines depending on what is in A1:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Range("A1"), Target) Is Nothing Then
Application.EnableEvents = False
Select Case Target.Value
Case "A"
FunctionWhenA
Case 1
ThasIsAnotherFunction
End Select
Application.EnableEvents = True
End If
End Sub
note that I also disable/enable events so this isn't triggered every time a cell is changed
There are two main types of Excel macros
1- Those that are written to perform actions, change data, etc.
2- And those that are written to perform calculations and return values to certain cells
(used as customized formulas that are not built in to excel)
The first type can only be triggered to start execution by clicking a button on a form, invoking the Macros window within Excel and selecting the name of the macro to be run
The second type can be run as soon as a value of a certain cell changes (that cell must be an input for the said macro function to work with, calculate and return a certain output), and thus the returned value will be stored on another cell.
In the second type, Excel will ignore any code that tries to modify the content of other cells, perform actions on the worksheet, workbook, or any other action that is not limited to the cell contanining the formula for the custom macro.
If you intend to run a macro of the first type, and want it to be executed right after a certain value changes, then that is not possible.
If you want to write a macro of the second type, then that is possible but code will only be limited to a single cell only.
Yes would need to loop through them.
You could replace the "cas" subs in following with your implementation of VBA for that case.
Function Strange(myVal)
Select Case myVal
Case 1
Cas1
Case 2
Cas2
Case 3
Cas3
End Select
End Function
Sub Cas1()
MsgBox ("hi")
End Sub
Sub Cas2()
MsgBox ("ha")
End Sub
Sub Cas3()
MsgBox ("ho")
End Sub
Sub LoopThem()
Do While ActiveCell.Value <> ""
Strange (ActiveCell.Value)
ActiveCell.Offset(1, 0).Activate
Loop
End Sub
So cell A1 to A3 with values 1,2,3 would consecutively pop up msgboxes "hi" "ha" "ho".
Fixed it.
Done this via using Intergers to stop when I have no further cells with data to stop the macro, and detect on many '1's are within the code and copy the data as neededs using "For" commands.

Automatic Text Capitalization Excel VBA

I'm currently trying to write a macro based on sheet change, where the letters in a table column are automatically converted to upper case. So, for example, if I entered "abcde-12345-678" into a cell, it would automatically correct to "ABCDE-12345-678". After doing some digging, I found some code that has worked for some people, but I'm having trouble tweaking it to suit my needs.
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("E:E")) Is Nothing Then Exit Sub
Application.EnableEvents = False
Target = UCase(Target)
Application.EnableEvents = True
End Sub
There are two things that I would like to address. The first being, that this code isn't currently working for me. I have it in the correct location according to the author (located in the Sheet1 object). Are there any ideas as to why this isn't working?
The second is that I would like to modify the code to refer to a table column rather than a range. For example, I've tried changing the second line of the above code to the following (the name of my table is ReviewTracker, and the column I'm interested in is Product Number):
If Intersect(Target, Range(ReviewTracker[[#Headers],[Product Number]])) Is Nothing Then Exit Sub
This returned a compile error "Expected: list separator or )". So there is obviously something wrong with it, but hopefully it might help illustrate what it is I'm trying to accomplish.
Thanks in advance for any help on the issue.
-Sean
First. You can have events disabled due to lots of reason. Let's make it sure that events are on which you can do as follows:
go to VBA Editor >> open Immediate Window >> write there: Application.EnableEvents = true >> press Enter
Second. To check if intersection match appropriate column within you ListObject table you need something like this:
If Intersect(Target, Range("ReviewTracker[Product Number]")) is Nothing Then
assuming that ReviewTracker is table name and Product Number is table column. You don't need #Headersas it will refer only to header row.
What UCase does is converting all the characters in a given string into upper case and thus you can apply it to any Range.Value. Worksheet_Change is called every time the value of a cell has changed and thus is a good place to put your code. But the way you are using to refer the table is wrong. The code your posted adapted to your requirements:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Sheet1.ListObjects("Table1").ListColumns(1).Range) Is Nothing Then Exit Sub
Target.Value = UCase(Target.Value)
End Sub
It converts into upper caps any string input in the first column of Table1 in Sheet1. It has to be placed in the Sheet1 object file (in the VBA Project explorer: Sheet1 (Sheet1) inside the Microsoft Excel Object folder). Adapting it to your actual conditions is straightforward.

Resources