I need some advise on an excel formula.
I have 6 cells (A1 to A6) - If ANY of them is "Y" then I want all the others to auto populate to "N".
Is there a way to do this?
Try following code
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range
Set rng = Range("A1:A6") 'set rng as A1:A6
If Not Intersect(Target, Target.Worksheet.Range("A1:A6")) Is Nothing Then
Application.EnableEvents = False
If UCase(Target) = "Y" Then 'check if entered value is Y
rng.Value = "N" 'make cells N
Target = "Y"
End If
Application.EnableEvents = True
End If
End Sub
Insert VBA code to Excel Workbook
Open your workbook in Excel.
Press Alt+F11 to open Microsoft Visual Basic Editor.
At the top left corner of the editor window, under Project-VBAProject pane, double click on the sheet name you want code to work for.
Copy above VBA code and paste it to the right pane of the VBA editor.
Finally, change the values in Range A1:A6 and you should get desired result.
To know how to enter this code in workbook see this.
Related
I am trying to show/hide a number of rows based on "n".
The rows I'm trying to show or hide span from rows 21 to 70. My input cell for "n" is B14.
Say if B14 is 2 then I only want rows 21 and 22 to be visible (23 to 70 hidden). If B14 is 48 then rows 21 to 68 visible and so forth.
Can someone help me with the macro required to achieve this?
Try this code, please. It will automatically hide the rows according to the changed value in "B14". Copy the code in the sheet module. In order to do that, select the sheet to be processed, right click on its page and choose "View Code". Copy the code there, go back in the sheet, start playing with values in "B14" and send some feedback about its behavior:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("B14")) Is Nothing Then
Dim lastRow As Long, visRows As Long
If IsNumeric(Range("B14").Value) Then
visRows = Range("B14").Value
Else
MsgBox "In range ""B14"" must be a number!": Exit Sub
End If
If visRows = 50 Then
lastRow = 69
Else
lastRow = 70
End If
Range("A:A").EntireRow.Hidden = False 'make all rows visible
Range(Range("A21").Offset(visRows), Range("A" & lastRow)).EntireRow.Hidden = True
End If
End Sub
The following VBA code should work
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rngWatched As Range, n As Long
Set rngWatched = Me.Range("B14")
If Not Intersect(Target, rngWatched) Is Nothing Then
With Me.Range("A21:A70")
.EntireRow.Hidden = True
n = rngWatched.Value
If n > 0 Then
.Cells(1, 1).Resize(n, 1).EntireRow.Hidden = False
End If
End With
End If
End Sub
To use the code, please follow these steps:
Press Alt+F11. This will take you to the VBA editor window
On the left hand side you will see a project explorer
Expand VBAProject(YOUR_EXCEL_FILENAME)
Expand Microsoft Excel Objects
Double-click on the relevant sheet. This will open the sheet class page
Paste the code here
Close the VBA editor window and go back to excel
Make sure the file is then saved as Excel Macro-Enabled workbook (*.xlsm)
I am designing a time report for my colleagues. There are cells which contain a (hidden) formula but are unprotected because I need the user to still be able to manually override the formula.
Now, if a user enters his/her own content and then deletes it again, the cell is empty, which is what I don't want, as it will only lead to confusion.
I want to write a VBA macro which recognizes if the cell contents in a previously declared range are deleted / empty and if they are deleted / empty, then a formula from another (password-protected and hidden) cell should be copied to the empty cell.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim myRange As Range
Set myRange = Intersect(Range("F9:I108"), Target)
If Not myRange Is Nothing Then
'I'm guessing something with WorksheetFunction and possibly CountA,
'but I don't know how to make it work
End If
End Sub
The formulas which should be entered if the content of a cell (or of multiple cells) is deleted is always in line 117 (same worksheet). For example, if the user deletes G50, then G117's formula should be copied into G50 in the same way you usually copy formulas in Excel (so if there's a non-$-reference in G117 that points to A117, it should then point to A50 after the formula is copied to G50).
If possible, I want to work without loops--they always take so long to execute.
Thanks in advance!
Here is a super simple example that involves only 3 cells, A1, A2 and A3. You must modify this to accommodate your formula-cells.
We first create a secret worksheet (called secret). We place the formulas from A1 through A3 from the main worksheet into the secret sheet, but we store them as Strings rather than Formulas:
Then we put the following worksheet event macro in the main sheet:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range
Set rng = Range("A1:A3")
If Intersect(Target, rng) Is Nothing Then Exit Sub
If Target.Count <> 1 Then Exit Sub
If Target.Value <> "" Then Exit Sub
Application.EnableEvents = False
Target.Formula = Sheets("secret").Range(Target.Address).Value
Application.EnableEvents = True
End Sub
The sub monitors changes to the three cells and if any of them are cleared, that formula will be restored from the secret worksheet.
Because it is worksheet code, it is very easy to install and automatic to use:
right-click the tab name near the bottom of the Excel window
select View Code - this brings up a VBE window
paste the stuff in and close the VBE window
If you have any concerns, first try it on a trial worksheet.
If you save the workbook, the macro will be saved with it.
If you are using a version of Excel later then 2003, you must save
the file as .xlsm rather than .xlsx
To remove the macro:
bring up the VBE windows as above
clear the code out
close the VBE window
To learn more about macros in general, see:
http://www.mvps.org/dmcritchie/excel/getstarted.htm
and
http://msdn.microsoft.com/en-us/library/ee814735(v=office.14).aspx
To learn more about Event Macros (worksheet code), see:
http://www.mvps.org/dmcritchie/excel/event.htm
Macros must be enabled for this to work!
Here's another possible answer. In order to copy the formula and have it maintain the "relative addressing" of the formula, you need to copy using the R1C1 notation. So a quick sub for this could look like
Option Explicit
Sub RestoreFormula(ByRef emptyCell As Range)
Dim formulaWS As Worksheet
Dim formulaCell As Range
Set formulaWS = ThisWorkbook.Sheets("Sheet1")
Set formulaCell = formulaWS.Range("A17")
emptyCell.FormulaR1C1 = formulaCell.FormulaR1C1
End Sub
The important line here is the emptyCell.FormulaR1C1 = formulaCell.FormulaR1C1 part.
Then, over in the Worksheet_Change event it could look like this
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim checkRange As Range
Set checkRange = ActiveSheet.Range("A1:A9")
If Not Intersect(checkRange, Target) Is Nothing Then
Dim changedCell As Range
For Each changedCell In Target
If IsEmpty(changedCell) Then
RestoreFormula changedCell
End If
Next changedCell
End If
End Sub
If anyone else ever has the same problem and maybe wants to use my solution, which is a combination of PeterT's and Gary's Student's suggestions (thank you both so much):
First I created a new worksheet, in which I copied all of the formulas I wish to retain. I made sure to copy them to the exact same cell as in the original sheet.
Then I appended this code to the original worksheet:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim Bereich1 As Range
Set Bereich1 = Range("F9:I108") 'Do NOT enter multiple, non-contiguous ranges here! It crashes Excel!
If Not Intersect(Bereich1, Target) Is Nothing Then
Dim changedCell1 As Range
For Each changedCell1 In Target
If changedCell1 = "" Then
changedCell1.Formula = Sheets("Tagebuch_secret").Range(changedCell1.Address).Formula
End If
Next changedCell1
End If
Dim Bereich2 As Range
Set Bereich2 = Range("E112") 'instead duplicate the code snippet
If Not Intersect(Bereich2, Target) Is Nothing Then
Dim changedCell2 As Range
For Each changedCell2 In Target
If changedCell2 = "" Then
changedCell2.Formula = Sheets("Tagebuch_secret").Range(changedCell2.Address).Formula
End If
Next changedCell2
End If
End Sub
This works fine for every scenario in which cell contents get deleted, both if the user deletes contents of a single or multiple cells!
My next step is to make the _secret sheet very hidden, password-protect the workbook structure and then password-protect my vba project. Then only people who know the password (me) can destroy my file :)
The following VBA script for an Excel sheet allows an individual to type text into a cell and then automatically jump to the next cell in the array once they hit enter.
However, this requires someone to type into every cell for the script to advance to the next cell in the array below and does not recognize tab, only enter.
Private Sub Worksheet_Change(ByVal Target As Range)
Dim tabArray As Variant
Dim i As Long
tabArray = Array("B5", "C6", "D7", "E8")
Application.ScreenUpdating = False
For i = LBound(tabArray) To UBound(tabArray)
If tabArray(i) = Target.Address(0, 0) Then
If i = UBound(tabArray) Then
Me.Range(tabArray(LBound(tabArray))).Select
Else
Me.Range(tabArray(i + 1)).Select
End If
End If
Next i
Application.ScreenUpdating = True
End Sub
I'd like to let the person hit tab or enter if they want to skip the given field and advance without typing anything in the cell.
You can also just protect the sheet and have the input cells unlocked.
Right Click on the Cell, choose "Format cells".
Then, go to Protection Tab, and uncheck "Locked".
Once the input cells are unlocked, go to the "Review" Ribbon, and click on Protect Sheet. Uncheck "Select locked cells" and it should only allow you to click on the cells that are unlocked, and can press Tab repeatedly to go to the next available cell.
Protecting the sheet and unlocking the data-entry cells as suggested by #Basher is probably a better solution IMO, but this sort-of works. Couple of notes:
To "break into" the tab sequence you need to select one of the data-entry cells
To "break out" of the tab sequence (so you can select some other cell maybe) you can make a multi-cell selection.
Code:
Dim lastCellAddress As String
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim tabArray As Variant
Dim i As Long, addr, mCurr, indx, mPrev
If Target.Cells.CountLarge = 1 Then
tabArray = Array("B5", "C6", "D7", "E8")
addr = Target.Address(False, False)
mCurr = Application.Match(addr, tabArray, 0)
If IsError(mCurr) Then 'current selection isn't a data entry cell
If lastCellAddress <> "" Then
'was user previously in a data entry cell?
mPrev = Application.Match(lastCellAddress, tabArray, 0)
If Not IsError(mPrev) Then
'mPrev is 1-based but tabArray is 0-based...
indx = IIf((mPrev - 1) < UBound(tabArray), mPrev, 0)
On Error GoTo haveError
Application.EnableEvents = False
Me.Range(tabArray(indx)).Select '<< select the next entry cell
Application.EnableEvents = True
End If
End If
End If
lastCellAddress = Selection.Address(False, False)
Else
lastCellAddress = "" 'breaks out of the sequence
End If
Exit Sub
haveError:
Debug.Print Err.Description
Application.EnableEvents = True
End Sub
You don't need VBA to achieve this task - it's a built-in Excel functionality.
Simply select your data entry range and after inputting the desired value into the first cell hit TAB, it will take you to the next highlighted cell - either to the right of the current one or to the next row if you were at the end of the row.
I have a worksheet with values in columns B:G. In the same sheet in cell A1 I have made a drop down list using data validation with values like A, B and C.
What I require is when I select cell value A then columns B:C need to be visible and the other columns should be hidden from D:G. In the same way if I select B from the list I need to view columns D:E and B:C and F:G should be hidden.
Could you please help me on this.
Note: I don't have good knowledge in VBA.
Try this:
Open the VBA editor (ALT + F11)
Double click Sheet1
Select Worksheet in the top left drop down and Change in the top right hand drop down
Paste this code
NB- this assumes data validation is in cell A1
Private Sub Worksheet_Change(ByVal Target As Range)
Dim allColumns As Range
Set allColumns = Columns("B:G")
allColumns.Hidden = True
If Not Intersect(Target, Range("A1")) Is Nothing Then
If Target.Value = "A" Then
Columns("B:C").Hidden = False
ElseIf Target.Value = "B" Then
Columns("D:E").Hidden = False
ElseIf Target.Value = "C" Then
//Add more logic here
End If
End If
End Sub
Go to view --> macros.
Hit the dropdown and do "record new macro".
Right click on a column header and do hide column.
Then do unhide column.
Do Macros->stop recording.
Macros-->View macros
Click edit.
you get the following code:
Columns("C:C").Select
Selection.EntireColumn.Hidden = True
Selection.EntireColumn.Hidden = False
Now you know how to hide and show columns. First you select the column then your set Hidden = true or false.
Google: excel macro when cell value changes
Click the first link: http://support.microsoft.com/kb/213612
Take the code from that link and read the comments:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim KeyCells As Range
' The variable KeyCells contains the cells that will
' cause an alert when they are changed.
Set KeyCells = Range("A1:C10")
If Not Application.Intersect(KeyCells, Range(Target.Address)) _
Is Nothing Then
' Display a message when one of the designated cells has been
' changed.
' Place your code here.
MsgBox "Cell " & Target.Address & " has changed."
End If
End Sub
Make sure you read the link very closely. And follow the instructions. I find I sometimes rush and miss important details
Let me know if this is enough or you need more help.
It's been a long time, but it may still be useful to someone.
Userform to hide-unhide worksheet’s columns :
The userform that we created to hide the columns in the workbook and unhide the hidden columns contains also a button to minimize userform. With to the drop-down list in the userform can be navigated between worksheets, the selected worksheet from the combobox is active and the column management(hide-unhide) of this worksheet is provided.
Explanations and sample Excel file here
Is there a simple way to do this, via macro or otherwise? By calculated field I mean a field that is computed from other fields, versus raw entered values. By highlight I mean colored differently. I need this to better understand a large spreadsheet from a client.
To do it manually, press the F5 key to bring up the GoTo dialog. Click the Special Cells button. On the next screen, select Formulas (it's an option on the right).
Excel will select all of the cells that match. Now it's just a matter of applying formatting.
I'm going to assume you're only talking about cell formulas rather than VBA calculations here, since you could set the cell colour in your VBA procedure if you're doing it that way.
The way to do this is to check the cell for a formula after you're done with it, and change it's colour at that point. The relevant event here is Change, and the cell's HasFormula property will tell you whether the cell is a literal value, or calculated from a formula:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.HasFormula Then
Target.Interior.Color = vbRed
Else
' remove background colour entirely (i.e. No Fill)
Target.Interior.ColorIndex = xlColorIndexNone
End If
End Sub
TLDR;
Use Conditional Formatting with a Formula to highlight all cells that contain a formula.
Details
In MS Office 365 Version: 5.0.4667.1002, the following works
Select a range of cells.
Case1: Use Ctrl + A to select all cells.
Case2: Select a specific range.
Go to the Home tab, Styles section, and choose Conditional Formatting > New Rule.
The "New Formatting Rule" dialog will open.
Choose "Use a formula to determine which cells to format"
In the textbox, add the following rule: =IsFormula(A1)
Case1: If you selected all cells, use A1 because it is the first cell.
Case2: If you selected a specific range, replace A1 with the first cell in your range.
Click Format...
The "Format Cells" dialog will open.
Choose the format you would like to apply. E.g. a yellow background.
Click OK.
All cells that have formulas will now have, for instance, a yellow background.
Screenshot
Excel has a built in feature of "Trace Dependents" (which shows arrows to show you the calculated cells)
Select the range containing your data.
Excel 2007 -> Formulas -> Trace Dependents
The code below should cycle through each sheet, highlighting every cells that starts with an '=' and colors it the desired color (currently colour 36 which is Light Yellow).
Sub HighLightFormulas()
Dim objSheet As Worksheet
Dim strOriginalSheet As String
Dim intMaxBlankCells As Integer
Dim intBlankColumns As Integer
Dim intBlankRows As Integer
Dim intCurrentColumn As Integer
Dim intCurrentRow As Long
intMaxBlankCells = 40
strOriginalSheet = ActiveSheet.Name
For Each objSheet In Worksheets
intBlankRows = 0
intCurrentRow = 1
intCurrentColumn = 1
Do While intCurrentRow <= 65536 And intBlankRows <= intMaxBlankCells
intBlankColumns = 0
intCurrentColumn = 1
Do While intCurrentColumn <= 256 And intBlankColumns <= intMaxBlankCells
If Left(objSheet.Cells(intCurrentRow, intCurrentColumn).Formula, 1) = '=' Then
objSheet.Cells(intCurrentRow, intCurrentColumn).Interior.ColorIndex = 36
End If
intCurrentColumn = intCurrentColumn + 1
Loop
If intCurrentColumn = intBlankColumns Then
intBlankRows = intBlankRows + 1
Else
intBlankRows = 0
End If
intCurrentRow = intCurrentRow + 1
Loop
Next objSheet
Worksheets(strOriginalSheet).Activate
Call MsgBox("The Highlighting process has completed", vbOKOnly, "Process Complete")
End Sub
It will also stop after 40 consecutive blank cells (to avoid processing all of a mostly blank sheet).
Hope this helps.
Simple solution:
Ctrl - ` (the key just above Tab)
You can use the Interior.ColorIndex property to change the active cell's background color:
ActiveCell.Interior.ColorIndex = 36
You may also apply it to a range:
Range("A1:A5").Interior.Color = RGB(200,160,35)
This applies to Excel 2003, I haven't used the latest version but I doubt this has changed.
You can usually record a macro and then look at the generated code to see how something is done.
I liked Craig's code here, because it keeps the layout of the existing worksheet and yet shows what is calculated and what is not 'at a glance', but I have reworked it a bit so it does a better job of working out the active area of sheets, and I added an 'UnhighlightFormulas' subroutine so one can easily undo the formatting (e.g. before printing). It has been tested in Excel 2007. Note that you will lose any other cell background colouring upon running this.
Option Explicit
Public Sub HighlightFormulas()
ColorFormulas (36) '36 is yellow
End Sub
Public Sub UnhighlightFormulas()
ColorFormulas (-4142) '-4142 is default
End Sub
Private Sub ColorFormulas(intColor As Integer)
Dim wshSheet As Worksheet
Dim rngRange As Range
Dim rngCell As Range
For Each wshSheet In Worksheets
Set rngRange = RangeInUse(wshSheet)
If Not rngRange Is Nothing Then
For Each rngCell In rngRange
If Left(rngCell.Formula, 1) = "=" Then
If rngCell.Interior.ColorIndex <> intColor Then rngCell.Interior.ColorIndex = intColor
Else
If rngCell.Interior.ColorIndex <> -4142 Then rngCell.Interior.ColorIndex = -4142 '-4142 is default
End If
Next
End If
Next
End Sub
Private Function RangeInUse(ws As Worksheet) As Range
Dim LastRow&, LastCol%
' adapted from http://www.beyondtechnology.com/geeks012.shtml
' Error-handling in case there is no data in worksheet
On Error Resume Next
With ws
LastRow& = .Cells.Find(What:="*", SearchDirection:=xlPrevious, SearchOrder:=xlByRows).Row
LastCol% = .Cells.Find(What:="*", SearchDirection:=xlPrevious, SearchOrder:=xlByColumns).Column
End With
Set RangeInUse = ws.Range("A1", Cells(LastRow&, LastCol%))
End Function