Excel enter formula into cell - excel

Function bd()
Sheets("sheet1").Range("A1").value=1
End Function
This is my function.
Why is it that when i enter =bd() into any cell in sheet1, the data in A1 does not change to 1? I do not want to use the button to change the value.

Why it does not work:
If you're calling your function from an Excel formula, your function becomes a User-Defined-Function (=UDF).
UDF have to follow special rules - the main one being that it cannot by any means change anything in Excel - it shall only return a value! Your function clearly violates this rules.
(For reference: the other main restriction is that it shall also not access any data outside the parameters that were passed to it when calling the function. Thus, you cannot use MyUDF=Range("A1").Value - but only something like MyUDF=rngParam1.Value*2!
Alternative approach:
If you want to change the worksheet but don't want to use a button, you need to think of some kind of trigger event. Look at the possible Worksheet and workbook events - you'll find a list of events here - and detailed instruction how to use them here.
For instance, you could use the Activate of Sheet1. For this place this code in the Sheet1 code module:
Private Sub Worksheet_Activate()
Range("A1").Value = 1
End Sub
Now every time that sheet1 gets activated, A1 will be reset!

Try This
Copy this code on your 'Thisworkbook' on vba
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
If ActiveSheet.Range("A1").Value = "bd()" Then
Sheets("sheet1").Range("A1").Value = 1
End If
End Sub
Now if you enter 'bd()' (without Quotes) on cell A1 on Any Sheet and press enter the cell A1 of Sheet one will Change to 1
OR
Copy this code on your 'Thisworkbook' on vba
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
If Sheets("sheet1").Range("A1").Value = "bd()" Then
Sheets("sheet1").Range("A1").Value = 1
End If
End Sub
Now if you enter 'bd()' (without Quotes) on cell A1 on Sheet one and press enter the cell A1 of Sheet one will Auto Change to 1
Hope this works

Related

AutoFit on rows that are referenced from different sheet using function - VBA

I would like to make an autofit to the referenced cells from another sheet, so everytime when I add some infos on one sheet my row height expands, the code below makes that possible:
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Target.WrapText = True
Target.EntireRow.AutoFit
End Sub
But as I say this is possible only if I manually typing something anywhere in my workbook, but what about when I have on another sheet (same workbook) some functions that are referencing those values? the fields are not expanding even though it is a right match...
For instance I am having this infos in one sheet (wrapped) as one value:
Column A
AAABBBCCCDDD
EEEFFFGGGHHH
and when using this function on another sheet to make them referenced:
=IFNA(IF(ISBLANK(INDEX(INDEX(Table1[Systembezeichnung];MATCH(Ausdruck!$A$5;Table1[Nummer];0)):INDEX(Table1[Systembezeichnung];MATCH(Ausdruck!$A$5;Table1[Nummer];0)+9);ROW(4:4)));"";INDEX(INDEX(Table1[Systembezeichnung];MATCH(Ausdruck!$A$5;Table1[Nummer];0)):INDEX(Table1[Systembezeichnung];MATCH(Ausdruck!$A$5;Table1[Nummer];0)+9);ROW(4:4)));"")
it gives me everything in one row but not expanding or wrapped as I want:
Column A
AAABBBCCCDDDEEEFFFGGGHHH
It has to be automatically wrapped for the sake of dynamic document that I am providing, without loss of infos or that some infos are missing or "hidden".
You can use Workbook_SheetCalculate event. A simple example will be like below.
Private Sub Workbook_SheetCalculate(ByVal Sh As Object)
With Worksheets("Sheet2")
.Range("D2:D5").WrapText = True
.Range("D2:D5").EntireRow.AutoFit
End With
End Sub
So, if you have any formula to range D2:D5 on sheet2 and when you will change any value to any sheet of workbook and if it changes any value to D2:D5 then that cell row will automatically fit.
Edit: For full sheet you can try below codes.
With Worksheets("Sheet2")
.Cells.WrapText = True
.Cells.EntireRow.AutoFit
End With
Microsoft reference here

How to run a macro in a specific Sheet, but control the start based on a Value maintained from another Excel File/Sheet?

Hi,
How to run a macro in the background in a specific Sheet, and only work with and control the trigger of the Macro based on a calculated Value maintained in another Excel File/Sheet?
The use case is that I want to run a Macro named “TargetCalc” – which trigger either Marcro_01 or Marcro_02 in a specific Sheet depending if Cell C3 in that Sheet has the value 1 or 2.
The Macro example below works nice if everything is maintained or calculated within the active Excel Sheet itself. But - if I instead want to control the value in Cell C3 from a completely another Excel File I have open (where my focus is), then I get the error message “Run-time error ’9 ’: Subscription out of range”
The Test setup:
Save an Excel File named “DisplayExcelFile.xlsm” and rename “Sheet1” to “DisplaySheet1”
Copy the VBA Code seen below
In the File “DisplayExcelFile.xlsm” - in Cell C3, enter: =IF(D3<100,1,2)
In the File “DisplayExcelFile.xlsm” - in Cell D3, enter the value 105
Result:
a) Cell C3 will display 2 because Cell D3 is 105, which is more than 100 => Macro_01 is triggered
b) If you manually update Cell D3 from 105 to 78 => Macro_02 is triggered
So far so good – and this example works nice.
Open a 2nd Excel on the same machine – and rename “Sheet1” to “CalcSheet” and Save this Excel File with the name “CalcFromExcelFile.xlsm”
In the File “CalcExcelFile.xlsm” - in Cell A2, enter the value 130
Next: Have both Excel Files opened on the same machine – and Go back to the first Excel File “DisplayExcelFile.xlsm” Cell D3 and change Cell D3 from a value (105 or 78…) to instead a formula that refers to the other Cell A2 in the other opened Excel File: =[CalcFromExcelFile.xlsm]CalcSheet!$A$2
Result:
a) As long as the “focus” is within Sheet named “DisplaySheet1” in the first “DisplayExcelFile.xlsm” – the functionality works as expected when updating the Cell D3 with different numbers.
b) BUT: If you instead have “focus” in the second Excel File “CalcExcelFile.xlsm” and update the Cell A2 in the second Excel File to the Value 97 – Then the macros in the Sheet “DisplaySheet1” in the first “DisplayExcelFile.xlsm” does not work.
The popup VBA error says:
Run-time error ’9 ’: Subscription out of range
And when I “Debug” – it points to the row for the Macro_01:
“Worksheets("DisplaySheet").Range("A3").Select”
In addition:
The workflow I’m after is to have both Excel Files opened on the same machine – where the First Excel File “DisplayExcelFile.xlsm” is for Display Purpose and running the Macros – but all manual updates (the focus) is on the second Excel File “CalcFromExcelFile.xlsm”.
The Sheet will always be named “DisplaySheet1” in the first “DisplayExcelFile.xlsm” – so there is no need to modify the code so that it will work in case I rename the Sheet. My hope is that when I get this use case working, I will then create a 2nd and 3rd Sheet (“DisplaySheet2” and “DisplaySheet2” within the same First Excel File – so that I can replicate the same thing for these Sheets as well.
When I tried to get the VBA code working - I tried to make a direct reference to the Sheet name – and I also tried to improve the usage of “Select”, but I got stuck.
The Code
Module1
Option Explicit
Public TargetValue As Variant
Private Const cTarget As String = "C3"
Sub TargetCalc(ws As Worksheet)
'
If ws.Range(cTarget) <> TargetValue Then
Application.EnableEvents = False
Select Case ws.Range(cTarget).Value
Case 1
Macro_01
Case 2
Macro_02
End Select
TargetValue = ws.Range(cTarget).Value
Application.EnableEvents = True
End If
End Sub
Sub Macro_01()
'
Worksheets("DisplaySheet").Range("A3").Select
ActiveCell.FormulaR1C1 = "Hi_01"
Application.Wait Now + TimeValue("0:00:01")
ActiveCell.FormulaR1C1 = "There_01"
End Sub
Sub Macro_02()
'
Worksheets("DisplaySheet").Range("A3").Select
ActiveCell.FormulaR1C1 = "Hi_02"
Application.Wait Now + TimeValue("0:00:01")
ActiveCell.FormulaR1C1 = "There_02"
End Sub
Sheet1 (DisplaySheet)
Option Explicit
Private Sub Worksheet_Calculate()
TargetCalc Me
End Sub
ThisWorkbook
...empty...
Thanks a lot!
Don't select anything, [almost] ever. If you tell VBA the address, VBA will find it. Therefore you need to sort through your workbooks and worksheets with great care. I usually do this before I start programming. That's why you find the definitions at the top of my code below.
Don't worry about the sheet names. The first tab on the left is always Worksheets(1). You can address it by its index number. I think you will probably stick with names like "DisplaySheet1" in the display book but use the index in the calculation workbook. Point is: identify workbooks and worksheets precisely. Note that a worksheet, once defined with a Set statement, knows the workbook to which it belongs and you can retrieve that book's name with `Ws.Workbook.Name'.
Note that ThisWorkbook identifies the workbook in which the code resides whereas ActiveWorkbook is the one that has the focus. They could be the same but must not be the same necessarily.
Don't bother with macro numbers. Instead, learn about arguments. A macro that does essentially one job, like your Macro_01 and Macro_02, can be combined into one macro with the 1 or 2 supplied as an argument.
The code below will help you on your way.
Option Explicit
Sub Main()
' 149
Dim WsDisplay As Worksheet
Dim WsCalc As Worksheet
Dim Arg As String
Set WsDisplay = ThisWorkbook.Sheets(1)
Set WsCalc = ActiveWorkbook.Sheets(1)
If WsDisplay.Cells(3, "D").Value < 100 Then
Arg = 1
Else
Arg = 2
End If
' ' Note: I would use the following in place of the above
' ' because it's only a single line
' Arg = 2 + (WbDisplay.Worksheets(1).Cells(3, "D").Value < 100)
Action WsDisplay, Arg
End Sub
Private Sub Action(WsDisplay As Worksheet, _
ByVal Switch As Integer)
' 149
Dim Target As Range
Dim Txt As String
Select Case Switch
Case 1
Set Target = WsDisplay.Cells(3, 1) ' 1 = column A
Txt = "Hi"
Case 2
Set Target = WsDisplay.Cells(3, 2) ' 2 = column B
Txt = "Hello"
Case Else
MsgBox "Invalid switch"
Exit Sub
End Select
With Target
.Value = Txt
.Offset(1).Value = "there!"
End With
End Sub
Look for the worksheet and workbook definitions in the Main procedure. The design is to let the CalcSheet be the active one but, later in the code, that sheet is never used. All the action is on the inactive DisplaySheet.
Macro_01 and Macro_02 need to know which workbook they're operating on.
Eg:
Sub Macro_01()
With ThisWorkbook.Worksheets("DisplaySheet").Range("A3")
.Value = "Hi_01"
Application.Wait Now + TimeValue("0:00:01")
.Value = "There_01"
End With
End Sub

VBA program to run automatically

I have a worksheet with two tabs and wanted to have a VBA to run automatically and pop up a window message saying "NPV negative! Please enter future Savings!" anytime cell J27 (in both tabs) calculates negative value.
I have the below code in the Module and when I test and click run it does what I wanted to do but in reality when I change information and cell J27 is a negative number nothing happens. I'm very new with VBA so any help is appreciated.
Private Sub Worksheet_Calculate()
For Each cell In Range("J27")
If cell.Value < 0 Then MsgBox ("NPV negative! Please enter future Savings!"), , "Invalid Entry"
Next cell
End Sub
Thank you!
The Worksheet_Calculate subroutine is only going to be triggered when the worksheet that you created it in is recalculated. Range("J27") is only looking at the cell in that worksheet, so your loop only iterates one time.
To get the value in cell J27 from both worksheets, you need to specify the sheet and the range for each one.
Private Sub Worksheet_Calculate()
If Sheets("This Sheet").Range("J27").Value < 0 And _
Sheets("That Sheet").Range("J27").Value < 0 Then
MsgBox ("NPV negative! Please enter future Savings!"), , "Invalid Entry"
End If
End Sub
Put that in both worksheets to get it to run when either worksheet is recalculated. (Or, better yet, save it in a separate Module and call it from both Worksheet_Calculate subroutines.)

Excel VBA cell comboBox (data validation list) set selected index?

I am using Excel VBA to make an simple app, I have a CELL with Data Validation make it a "ComboBox", can I use VBA code to set the selectedIndex for it? and how?
If I understood correctly and you need to "put some value into CELL when worksheet with CELL on it is opened" then try to insert following code into ThisWorkbook module:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
If Sh.Name = "%%SheetWithCELL%%" Then
Sh.Range("CELL").Value = "%%NeededValue%%"
End If
End Sub
Where
%%SheetWithCELL%% - Name of sheet where CELL is located;
%%NeededValue%% - Value, which you need to insert into CELL.
P.S. Code assumes that "CELL" is the actual name of some cell (named range)

Workbook_SheetChange not triggered by change from formula in other worksheet

I'm trying to imlpement a code that displays a message when a certain condition is met. In this case, it should happen when Sheet2's A1's value is equal or bigger than 1000. This value, on the other hand, is defined by a formula located in Sheet1. I tried implementing a solution based on this thread: How can I run a VBA code each time a cell get is value changed by a formula?
So I got this:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim updatedCell As Range
Set updatedCell = Range("A1")
If Not Application.Intersect(updatedCell, Range("A:A")) Is Nothing Then
If updatedCell.Value >= 1000 Then
MsgBox "Something requires attention"
End If
End If
End Sub
When I change the value of A1 through something from Sheet2, it works, but if for example I define it as =Sheet1!A7, and change Sheet1's A7, nothing happens.
How could I make it work?
Well, the linked thread deals with the problem that you want to find out the cell that is recalculated by the current change. (Anyway, the Dependents method only works for formula on the active sheet so this would not work across sheets).
In your case, you already know that you only want to monitor one specific (formula) cell.
So, I'd simply go with this:
Put this code in sheet 1 if you know that Sheet2!A1 only depends on values on sheet1.
Just catch all changes and look at your cell each time:
Private Sub Worksheet_Change(ByVal Target As Range)
If Worksheets("Table2").Range("A1").Value >= 1000 Then
MsgBox "Something requires attention"
End If
End Sub
Make sure that you use Worksheets(...).Range - a blank Range can be the source of sleepless nights of error-hunting, it refers to the worksheet where the code is located if the code is in a worksheet module and to the active sheet if it is in another code module.

Resources