I was wondering if I can use the active cell, by that I mean the cell that is "highlighted" at a given time with the square border after there was a mouse click there, as an argument in a function.
For example, I have created a table with weighted averages with 3 weights: w1 is given in the column headers (kindly see the file below), w2 in the row headers, and w3 which complements w1 and w2 to 1.
What I'd like to do is have cells outside the table show the weights the average got when a cell in the table is selected.
For example:
Screenshot: http://imgur.com/emmBH5S/
file can be found here: https://drive.google.com/file/d/0B_7-00fdslR7Tm11ODRVS296ckk/
Here we see the cell K12 is active,
and for K12 w1=0.2, w2=0.15, and so, the cells in the weights tables above (rows 3-4) get the appropriate values according to the weights in the active cell.
(of course I manually created this one for illustration purposes)
Is there a way to do that? Preferably without VBA if possible
Couldn't find anything very useful...
Thanks in advance!
A
You don't need VBA (although you may prefer it).
W1: =INDEX($F$8:$AA$29,1,MAX(COLUMN(INDIRECT(CELL("address")))-(COLUMN(F8)-1),1))
W2: =INDEX($F$8:$AA$29,MAX(ROW(INDIRECT(CELL("address")))-(ROW(F8)-1),1),1)
W3: =J4-(G4+H4)
The CELL function with the address argument returns the address for whichever cell is active. I use INDIRECT to convert that address (just a string) to a cell reference. Then I use
=INDEX(Range, 1, Column of Reference)
to get the w1 value - the value in the first row and the same column as the active cell. The formula doesn't care what cell you make active, so I stuck a MAX in there so it would return a zero if you're out of the range.
Note that simply selecting a cell won't trigger the change. Once you select a cell, press F9 to calculate the sheet to get the proper results.
You need to use VBA. Following your example place this code in your Sheet object
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Row > 8 And Target.Column > 6 Then
Range("G4").Value = Cells(8, Target.Column).Value
Range("H4").Value = Cells(Target.Row, 6).Value
Range("L4").Value = Cells(Target.Row, Target.Column).Value
End If
End Sub
Cell L4 shows your selected cell value which can be used in other formulas.
EDIT
To place your code you go to VBA window and double click on the Sheet object where you have your data. (Marked with an arrow in the picture)
Then paste yout code.
Related
I am trying to use some sort of trigger to allow the user of this sheet to take an outputted value (through an algorithm I created) and transcribe it into another sheet.
The cell that it should transcribe the value to will be determined by taking the row name and column name from the user.
In this example, the user would insert X and Y as their row name and column name respectively. Once they click the trigger button (does not have to be a button, I am willing to use any type of trigger, but I assume there must be one in order for this to work), the value in the "Value (Rounded)" labeled cell will be transcribed to the corresponding cell:
This cell is where I want to insert the value.
The goal of this is automation. Ideally the user only needs to input the row name and column name and press a button (or any other trigger), which will transcribe the value into the other sheet.
Does this have to be VBA? This can be done with a pretty simple formula.
Assumptions:
The input sheet is named Input (change all references to Input to be the actual name of that sheet)
The row name is in cell B1 (change Input!$B$1 to be the actual row name entry cell)
The column name is in cell B2 (change Input!$B$2 to be the actual column name entry cell)
The Value (Rounded) cell is in B4 (change Input!$B$4 to be the actual Value (Rounded) cell)
In cell B2 of our Output sheet, put in this formula and then copy over and down:
=IF(AND(Input!$B$1=$A2,Input!$B$2=B$1),Input!$B$4,"")
Adding a button can be done by creating a shape (rectangle or any other), right click it and select "Assign Macro". There you can select a macro which should be carried out after clicking that shape. One note though, the macro needs to be a "public sub".
You need to use event macro within the SHEET code (not module code). Here are two examples of how to get if a cell is changed or if a double click happens, both on specific cells:
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Not Intersect(Target, Range("E3")) Is Nothing Then
'Do something of Range("E3") has been double clicked
'(Basic Example)
'Range("G3").Value = "Range("B3").value
End If
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
'If a cell has chanced...
If Not Intersect(Target, Range("B3")) Is Nothing Then
'Do something
End If
End Sub
In reference to the picture below, I would like to loop through a certain column (Column D in this case) until I hit a specific cell (Yellow cells in this case). In my final spreadsheet I have multiple yellow cells that I would like to target. Once I hit a yellow cell, I would like to start a simple summation of the values one cell to the left of the yellow (Column C). I would like to keep summing the values until I hit a blank cell, which would indicate the end of the set.
Please let me know if you need any more clarification!
Here's some code that should get the job done. However you are going to have to adapt it to however you want to use it.
Dim Summation as Double
For Each Target in Range("D:D")
If Target.Interior.ColorValue = 6 Then
Summation = Summation + Target.Offset(0, -1).Value
End If
Next Target
I hope this helps. However, don't forget about FreeMan's suggestions about good question asking and using the macro recorder!
I was just wondering if you could help me better understand what .Cells(.Rows.Count,"A").End(xlUp).row does. I understand the portion before the .End part.
It is used to find the how many rows contain data in a worksheet that contains data in the column "A". The full usage is
lastRowIndex = ws.Cells(ws.Rows.Count, "A").End(xlUp).row
Where ws is a Worksheet object. In the questions example it was implied that the statement was inside a With block
With ws
lastRowIndex = .Cells(.Rows.Count, "A").End(xlUp).row
End With
ws.Rows.Count returns the total count of rows in the worksheet (1048576 in Excel 2010).
.Cells(.Rows.Count, "A") returns the bottom most cell in column "A" in the worksheet
Then there is the End method. The documentation is ambiguous as to what it does.
Returns a Range object that represents the cell at the end of the region that contains the source range
Particularly it doesn't define what a "region" is. My understanding is a region is a contiguous range of non-empty cells. So the expected usage is to start from a cell in a region and find the last cell in that region in that direction from the original cell. However there are multiple exceptions for when you don't use it like that:
If the range is multiple cells, it will use the region of rng.cells(1,1).
If the range isn't in a region, or the range is already at the end of the region, then it will travel along the direction until it enters a region and return the first encountered cell in that region.
If it encounters the edge of the worksheet it will return the cell on the edge of that worksheet.
So Range.End is not a trivial function.
.row returns the row index of that cell.
[A1].End(xlUp)
[A1].End(xlDown)
[A1].End(xlToLeft)
[A1].End(xlToRight)
is the VBA equivalent of being in Cell A1 and pressing Ctrl + Any arrow key. It will continue to travel in that direction until it hits the last cell of data, or if you use this command to move from a cell that is the last cell of data it will travel until it hits the next cell containing data.
If you wanted to find that last "used" cell in Column A, you could go to A65536 (for example, in an XL93-97 workbook) and press Ctrl + Up to "snap" to the last used cell. Or in VBA you would write:
Range("A65536").End(xlUp) which again can be re-written as Range("A" & Rows.Count).End(xlUp) for compatibility reasons across workbooks with different numbers of rows.
The first part:
.Cells(.Rows.Count,"A")
Sends you to the bottom row of column A, which you knew already.
The End function starts at a cell and then, depending on the direction you tell it, goes that direction until it reaches the edge of a group of cells that have text. Meaning, if you have text in cells C4:E4 and you type:
Sheet1.Cells(4,"C").End(xlToRight).Select
The program will select E4, the rightmost cell with text in it.
In your case, the code is spitting out the row of the very last cell with text in it in column A. Does that help?
.Cells(.Rows.Count,"A").End(xlUp).row
I think the first dot in the parenthesis should not be there, I mean, you should write it in this way:
.Cells(Rows.Count,"A").End(xlUp).row
Before the Cells, you can write your worksheet name, for example:
Worksheets("sheet1").Cells(Rows.Count, 2).End(xlUp).row
The worksheet name is not necessary when you operate on the same worksheet.
I created a macro to show the following:
If (I3<>0,I3*G3,H3*G3) and this repeats itself for cell N3, R3, V3, Z3 etc.
Option Explicit
Sub Eg()
Range("J3, N3,R3, V3,Z3,AD3,AH3,AL3,AP3,AT3,Ax3,BB3,XF3,BJ3").Formula = "=IF(RC[-1]<>0,RC[-1]*RC[-3],RC[-2]*RC[-3])"
End Sub
However this doesn't seem to work.
Let me explain a bit more how this should work:
This report needs to be downloaded from an application.
The macro needs to be attached to this report so that when I download the report the macro automatically runs this formula in the appropriate columns.
Also I'll have to populate the spreadsheet for all the rows with this formula.
The columns where the formula should sit are not blank but this needs to be catered for in the report automatically once the macro is run.
What am I missing here?
When you use Range.Formula = formulaAsString, and the range refers to multiple cells, you specify the exact formula string as required by (only) the first cell in the range, while appropriately using relative vs. absolute cell references because the assignment to multiple (succeeding) cells will occur as if you were pasting the first cell in the range into the others, exactly as if you'd done a copy & paste without VBA -- you use absolute addressing A1 vs. A$1 vs. $A$1 vs. $A1 etc... as desired to achieve the right alteration of the formula for the succeeding cells.
For example,
Range ("A1, C1, E1").Formula = "=A2+$A2"
will have the same result as
Range ( "A1" ).Formula = "=A2+$A2"
Range ( "C1" ).Formula = "=C2+$A2"
Range ( "E1" ).Formula = "=E2+$A2"
You are mixing up .Formula with .FormulaR1C1! Your string is R1C1 style, but you assign it to the A1 style formula.
Therefore, simply, change it to:
Range("J3, N3,R3, V3,Z3,AD3,AH3,AL3,AP3,AT3,Ax3,BB3,XF3,BJ3").FormulaR1C1 = _
"=IF(RC[-1]<>0,RC[-1]*RC[-3],RC[-2]*RC[-3])"
or
Range("J3, N3,R3, V3,Z3,AD3,AH3,AL3,AP3,AT3,Ax3,BB3,XF3,BJ3").Formula = _
"=IF(I3<>0,I3*G3,H3*G3)"
As Erik points out in his answer, also the later will work and adjust the formula for each cell in the same way (which is not necessary in R1C1 as the formula stays the same anyway...)
I have a data in excel which I want to make a VBA script to copy it into a new worksheet but in a different way.
For example, I have this in sheet1 in A1~A3 cells.
Adam(A1)
Sam(A2)
Smith(A3)
I want to use these cells and create the following in another worksheet using refedit control.
Adam(A1)
Adam(A2)
Adam(A3)
Adam(A4)
Sam(A5)
Sam(A6)
Sam(A7)
Sam(A8)
Smith(A9)
Smith(A10)
Smith(A11)
Smith(A12)
I have refedit control in place in VBA script, but I'm not sure how to increment cell numbers to make it copy and paste into a new worksheet. I would like to use refedit control so that I can assign any cells and make it copy and repeat itself. How do I do this in VBA script?
Check out the Range Rows, Cells, and Address properties. This should help. Your question is too vague for a direct answer.
(This will get you started.)
Range.Row Property
http://msdn.microsoft.com/en-us/library/bb221550(office.12).aspx
Returns the number of the first row of the first area in the range. Read-only Long.
Example
For Each rw In Worksheets("Sheet1").Rows
If rw.Row Mod 2 = 0 Then
rw.RowHeight = 4
End If
Next rw
To increment cells in Excel VBA, you can use the Offset-property of the Range-object, e.g.
ActiveCell.Offset(1, 1).Select
will select the cell one row down and one column to the right of the active cell.
To add to Geoffrey's answer about active cell - it would also require that you activate the sheet you are looking to input your values if it is a different sheet from the one that is currently active. Additionally you would have to activate a cell to use activecell and the activecell offset property.
For example
'Activates the name of the sheet you would like to activate
Sheets("Sheet2").Activate
'Activates cell A1
Range("A1").Activate
'Activates cell one row down, one column right
ActiveCell.Offset(1,1).Select
'if current sheet is not activate you just do Sheets("Sheet2").Range("A1").Activate
The offset property of ActiveCell refers to other cells based off of the current active cell.
For example-
Offset(row,column) -
First Argument -Positive values as the first argument refer you to rows below the current active cell and Negative values refer you to rows above the current active cell
Second Argument-Positive values as the second argument refer you to columns right of the current active cell and Negative values refer you to columns left the current active cell