In Excel, I would like to select a cell and then copy the contents to n number of cells below. Instead of using the "fill" drag option since the number of rows will be fairly large and require scrolling and then stopping at the correct cell I was looking for other options.
I am currently doing the the following:
In excel I select a cell and then on the top left corner it shows the cell (i.e. A1). Then to select the number of cells below it, I modify the top left box to a range such as A1:A10 which selects the range of cells. See attached image. I then use the shortcut key "Ctrl-D" which copies the first cell to the other cells.
Is there a way instead of mentally calculating the ending cell number, I can do something that effectively works "A1 + 10" in this box to select 10 cells below to select the A1:A10 range?
How about this way? Enter your formula in cell 1. Enter the number of copies (including the original) you want of it in the cell below it. Double-click on the number you entered and the formula is filled down.
To try, install the procedure below in the code module of the worksheet on which you want the action. (That's a module Excel set up when you created the sheet. Don't install the code in a standard code module that you have to insert yourself.)
Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
Const TriggerClm As String = "A"
Dim R As Long
With Target
If (.Column = Columns(TriggerClm).Column) And (.Row > 1) Then
R = Val(.Value)
If R Then
With .Offset(-1)
If .HasFormula Then
.Resize(R).FillDown
.Select
Cancel = True
End If
End With
End If
End If
End With
End Sub
You may wish or have to tweak the code. For example, the action is limited to column A. Change the constant at the top of the code to identify the column you prefer, or change the limits to better suit your requirements. The code also checks if Cell #1 contains a formula. If that isn't what you want to fill down that condition will have to be revised.
Last, but not least, the code selects Cell#1 (the one that contained the number is over-written). That may not be the best choice. You can modify the code to select a place in your worksheet where you will continue working.
Related
How might one turn spreadsheet cells into buttons, and execute VBA code, without inserting buttons, shapes or other active-X objects?
Using #TimWilliams' suggestion and referenced URL, based on readings there and further, I present some demonstration code, which works for me in Excel 2010: the IfError may not work in earlier versions, and I wonder if it behaves different in later versions.
Note: This code can not be debugged as one might with normal VBA. This is because it is executed on the "spreadsheet side", as a user defined function.
Place a formula in a cell (here, A2):
=IFERROR(HYPERLINK("#MyUDF()","CellText"),"Junk")
"CellText" will show in cell A2.
The "#...." points to the UDF. In combination with the Set statement in the code, it forces a "click" to execute, and only executes once on the click, rather than as a repeatable event executed when hovering and moving across the cell
The =IFERROR(HYPERLINK(...),...) is a workaround for the #name or other error., seen when using the mere =HYPERLINK(....).
Place this code in a module (a dimension and the UDF):
Dim j as integer
Function MyUDF() ' this is a user-defined-function
'NOTE: can't be traced when executed,
'so this creates debugging issues
Set MyUDF = Selection
Range("a1") = j
j = j + 1
End Function
Clicking on the URL in A2 will increment the value displayed in A1 - one increment per click.
To observe the hover effect:
Comment out the "Set Statement"
remove the quotes and pound sign around the UDF reference. The cell will now show "asdf" instead of "Test".
Roll across the URL, and cell A1 will increment as you move/hover.
To get the entire cell to cause execution of the UDF (and the incrementing value), turn on word wrap for the cell.
Notice how with the hover, the code is executed often as you move around in the cell. For me, the code does not execute if I stop moving while in the cell.
An Alternative to "putting a button in a cell"
Select a cell to execute code using the worksheet event: Worksheet_SelectionChange
Place the code in the specific sheet's module, not the WorkBook Module. Color/Border/Text the cell as you please; a cell-is-a-cell on any computer or screen. I use this to reference help loaded into a userForm, from a look up on a help worksheet, when the user clicks on a short label/description. This works on merged cells as buttons. Using cell/buttons avoids Active-X objects complaints from IT.
Things to think on, with the sample code, following:
Target.Address returns absolute addresses, using the "$" character
Use the Select Case in your code, even if you have one cell/button. This eases the path to adding cell/buttons, later
consider using named ranges on the spreadsheet, and reference them in the code. That way, VBA won't care if you move the cell/button
If you have merged cells for which you create a named range, remember that the named range, in the spreadsheet, only points to the top-left cell
However, the Target.Address for the merged area returns the full range, not just one cell. If your Select Case refers to the address of the Target's top-left cell, you avoid this problem.
use Target.Cells(1,1).Address
Bad choice for merged cells: don't use MergeArea.Address (MergeArea will not work on merged cells [only works on single cells]; it returns the merged range within which a cell lives.
*Sample Code*
'How to Make Cells into Buttons that execute code
' place code in the specific Worksheet module of interest
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' in this example, I create named ranges on the spreadsheet '
' [complicated names, here, so you can read what's what]:
' one cell: "Button_OneCellNameRange"
' one set of merged cells: "Button_MergedCellNameRange"
' [the reference is the top-left cell, only]
' a VBA created cell/button location [not very useful for later sheet edits]
Dim myVBACellButton As Range
Set myVBACellButton = Range("B2")
Debug.Print "Target Address: " & Target.Address
'merged cells will return a range: eg "$A$1:$D$3"
Debug.Print "Target.Cells(1,1).Address: " & Target.Cells(1, 1).Address
'merged cells will return the top left cell, which would match
' a named reference to a merged cell
Select Case Target.Cells(1, 1).Address
'if you have merged cells, you must use the ".cells(1,1).address"
' and not just Target.Address
Case Is = "$A$1"
MsgBox "Hello from: Click on A1"
' [execute a procedure/subroutine call, or more code, here...]
Case Is = myVBACellButton.Address
MsgBox "Hello from: Click on B2, a VBA referenced cell/button"
' "myCellButton" defined as range in VBA
'using a range named on the spreadsheet itself ...
' named ranges allow one to move the cell/button freely,
' without VBA worries
Case Range("Button_OneCellNameRange").Address
MsgBox "Hello From: Button Click on Button_OneCellNameRange"
Case Range("Button_MergedCellNamedRange").Address
'note that the address for merged cells is ONE CELL, the top left
MsgBox _
"Hello from: Button_MergedCellNamedRange.Address: " _
& Range("Button_MergedCellNamedRange").Address _
Case Else ' normally you wouldn't be using this, for buttons
MsgBox "NOT BUTTONS"
End Select
End Sub
I need to ad the next sequence number in Column A automatically when I fill enter the next value in Column B. This sounds confused. Just see the snap so you will get the clear picture.
This should be done without usual dragging option. Is there any way
Make the Value of A1 equal to 1 and then from the A2 use the formula:
=IF(B3<>"",A2+1," ")
Drag this formula for the whole column.
In my solution I have a drag, but it is to define the formula for each of the fields. (I'm not sure if is this you are trying to avoid when you say
without the usual dragging option
)
You may achieve this using macros. Formula will increase the file size and processing time.
Right click on the sheet name on sheet tab-->select view code-->paste below code--> save file as macro enabled workbook.
Private Sub Worksheet_Change(ByVal Target As Range)
On Error GoTo step
If Target.Column = 2 And Target.Value <> "" Then
Target.Offset(0, -1) = Target.Row - 1
End If
Exit Sub
step:
Exit Sub
End Sub
You can also do this without using macro and formula:
Type first 2 value to the cell to establish the pattern
highlight the cell range
Under Home tag -> select Fill -> choose Series
Follow the image and Select OK
If you convert your table to a List ("Table") and use a formula for the first column, that formula will "auto-extend" as new values are typed in under "Item"
Is it possible to select a specific cell in a range that changes depending on what cells are highlighted.
So if i Had;
Range("C1").Value = Application.WorksheetFunction.Sum(Selection)
It would sum the entire highlighted area and put the value in C1. Is it possible to only select some cells in the highlighted area. I know it sounds dumb, i realise can just highlight the cells i need but this is just a simplified version of the problem I've got.
What i'm asking is, is there a way in code to say;
"In the highlighted range, select the cell that is 2 columns to the right and 4 columns down from the top left boundary of the range"
Thanks
The Code for your question:
"In the highlighted range, select the cell that is 2 columns to the right and 4 columns down from the top left boundary of the range"
Selection.Cells(1).Offset(4,2).Select
in your case being Selection a Range you can use its methods/properties:
Range("C1").Value = Application.WorksheetFunction.Sum(Selection.Cells(5,3))
since Cells(5,3) reference a cell 2 columns to the right and 4 rows down offset the selection top-left one
You may be able to use the Worksheet_SelectionChange Event and examine the Target reference.
For example paste this test code into some sheet class:
Option Explicit
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Address = "A1" Then Exit Sub
Range("A1").Value = WorksheetFunction.Sum(Target)
End Sub
Something like this - obviously you're going to have all kinds of checks in there for Errors and the likes.
I'd also look at some way of disabling the code since you're going to have Events firing all over the place. Depends on your requirements.
How do you highlight an active row in excel in VBA. and then when another row is selected, return that row to base background color, and highlight the new row.
Also how to clear all rows highlighted, using a clear button on the user form.
so there are tow question here, one to high light and unhighlight active rows, and the other to just clear all high lights by pressing a clear button on the form.
I know I can highlight a row using Ret.EntireRow.Interior.ColorIndex = 6 but i cant find code to unhighlight.
Thanks for your help.
You can use your 'clear all' functionality before changing the color of the row of the cell that you navigated to.
Open the VB Editor and right click --> view code on the worksheet that you want the row highlighting to take place.
Paste in this code:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Me.Range("A1:XFD1048576").Interior.ColorIndex = 0
Target.EntireRow.Interior.ColorIndex = 6
End Sub
This code operates as follows: whenever a user changes his or her selected cell(s) on the sheet, the code will first clear the existing highlighting away in the entire sheet and then will apply new highlighting to the row of the target cell the user has moved to.
This line of code:
Worksheets("YourSheetName").Range("A1:XFD1048576").Interior.ColorIndex = 0
Will clear the colors from all cells in the worksheet.
You may want to limit the Range("A1:XFD1048576") to the usable range on your workbook as this will increase performance. On my machine I see a very subtle, but still noticeable, delay in the colors when I move the cells (because I am clearing all cells in the sheet instead of just the ones I want). If you do this, you probably wouldn't want to use the .EntireRow attribute, instead you would have to enumerate how far along the workbook you want the row to be highlighted.
Update
Try this code below, which eliminates the need to clear the entire worksheet. I used .ColorIndex=xlNone instead of setting it to 0 which should preserve your table formatting. I tested in Excel 2010 and I formatted some data as a table, it highlights the correct row and unhighlights the other row as well as leaving the table formatting in tact.
Sub Worksheet_SelectionChange(ByVal Target As Excel.Range)
Static rr
If rr <> "" Then
With Rows(rr).Interior
.ColorIndex = xlNone
End With
End If
r = Selection.Row
rr = r
With Rows(r).Interior
.ColorIndex = 6
.Pattern = xlSolid
End With
End Sub
The trick is using Static. This allows the variable to continue to exist after termination of the procedure, so it remembers the last row it highlighted and then performs the un-highlight action accordingly.
The procedure first checks to see that rr is set, if it is not then it moves on, if it is then rr represents the row that was previously highlighted.
This can be done without changing the base background color,
In 2 steps,
Set up a conditional formatting rule that highlights an entire row if a certain formula is true.
In the formula field, enter this formula:
=OR(CELL("row")=CELL("row",A1))
Write a macro that recalculates the selected cell(s) when a new selection is made.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Target.Calculate
End Sub
Hit Alt + F11 to get back to Excel and you'll have the active cell's row highlighted with the format you chose, without changing the base colors of the cells.
For detailed explanation visit,
highlighted the entire row of the active cell.
I'm working on a spreadsheet to record vehicle mileage. I'd like to manually enter starting mileage in F6 and ending Mileage in G6. I'd like the value of G6 to then automatically be copied to F7 and I'd enter the ending mileage in G7- and so on. The problem I have is dealing with weekends and holidays when 2 or 3 blank cells may occur. I've tried using something like =if(D9=""," ", G6), but this doesn't work.
I've also tried this function in VBA: =IF(D9=""," ",LastNonBlankCell(G8:G39)) [D9 is a datefield] and only ended up with 0's.
Function LastNonBlankCell(Range As Excel.Range) As Variant
Application.Volatile
LastNonBlankCell = Range.End(xlDown).Value
End Function
Do you really need the blank rows for weekends or holidays? If not, set D8 to the formula =workday.intl(D7,1) then copy it down as far as needed. If you need to allow for holidays, see the Excel documentation for WORKDAY.INTL. The list of dates will now contain only workdays, so the ending mileage for one row can be copied down to the next with no special handling.
This makes weekends and holidays harder to see at a glance. That can be addressed using conditional formatting. Setup formatting for the range D8:D<whatever>, use the formula =D8>(D7+1), and set the formatting to whatever stands out for you.
The following VBA macro will achieve your end goal in a slightly different way than what you asked about.
After you have installed the macro, when you double-click on a cell in column G, the macro will copy the last entered ending mileage to the cell to the left in column F.
For example, if the last ending mileage entry was in cell G6 and you double-click in cell G9, that entry will be copied to cell F9. You can then enter the new ending mileage in cell G9.
Private Sub WorkSheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
If Not Application.Intersect(Target, Range("G:G")) Is Nothing Then
Selection.Offset(0, -1).Value = Selection.End(xlUp).Value
Else
Exit Sub
End If
End Sub
To install the macro, right-click on the worksheet's name tab, select "View Code", and paste in the macro code. It won't work if you put the code into a regular module.