VBA: Insert number of rows based on cell value - excel

Looking for a way to insert X rows above cell B9 in my workbook. The value of X will change and can be found in cell B4. This seems very simple, but I can't get this portion of my code to work.
ActiveSheet.Range("B9").Select
Selection.EntireRow.Insert.Cells("B4"), CopyOrigin:=xlFormatFromRightOrBelow

You can use Resize to do that, and you don't need to Select at all.
Range("B9").EntireRow.Resize(Range("B4").Value).Insert CopyOrigin:=xlFormatFromRightOrBelow
Also, you should avoid ActiveSheet — instead, fully qualify the sheet using Sheets("YourSheetName") or a variable referencing the sheet in question.

Related

vba offset with reference to cell

I need to copy a column of data to another column on a different worksheet, pasting values only. The appropriate paste column is identified in a single cell. This cell will be changed manually each time the macro is applied. So one time I might want to copy/paste in the first column, so my identifier cell is 1. The next time I might input 5 in this cell so that I offset 5 columns to the right to copy/paste data. Thank you.
You can reference the columns in a worksheet using the Columns property. You can achieve what I think you're trying to do with code like this.
Dim col As Integer
col = SomeSheet.Cells(1,1).Value
FromSheet.Columns(col).copy
ToSheet.Columns(col).PasteSpecial xlPasteValues

Repeating Formula with Incrementing Cell Reference

So I have built a formula that has Absolute Cell References, and wanted to repeat the same formula down 3000 cells with each one referencing increment cells. (1st formula referring to Cell $A$1, 2nd formula referring to $A$2) I know that I could easily do this without referencing exact cells and the Fill Handle and this is currently how it's set up, however there's a very large number of people who work in this spreadsheet that have bad Excel manners, and regularly delete rows and cells or copy and paste, which breaks the formulas.
Rather than manually editing the same formula in each cell to change the references from relative to absolute, I was wanting to run a Macro to automatically run the formula for 3000 cells.
I had at first built a Macro that fills 20 cells with the formula, but it didn't adjust the formula based on the active cell. (Always entered with range $A$1:$A$20, and not $A$21:$a$40 when started further down) I changed the Macro to loop, but it looks with all formulas referencing $A$1 rather than updating.
The Macro set up to loop is as follows:
Sub HDDatesRef()
ActiveCell.Select
ActiveCell.FormulaR1C1 = "=IF(AND(HD!R1C1>0,ISBLANK(HD!R1C4)),HD!R1C1,""n/a"")"
ActiveCell.Offset(1, 0).Range("A1").Select
Loop Until ActiveCell.Value = ""
End Sub
Any and all help with figuring this out would help immensely. Right now I also have access to Liknedin Learning, so if there's any suggestions for courses on there I should look into so I can understand what I need to do will help with this.
The Excel application object has a function called ConvertFormula which you can use to change a formula between reference styles (A1 or R1C1) and to specify whether the rows and columns should be relative references or absolute references.
If you start off by creating the formula in each row as a relative reference then you can use ConvertFormula to turn it into an absolute reference. The only restriction is that the formula cannot be longer than 255 characters.
Adapting your code and following the advice in How to avoid using Select in Excel VBA gives us:
Option Explicit
Sub HDDatesRef()
Dim r As Range
' If we know the cell address we want to start in then we could use that directly
' e.g. Set r = Worksheets("HD").Range("E1")
Set r = ActiveCell
Do
' The With block just saves us typing r.FormulaR1C1 multiple times
With r
' Don't know what your relative formula would be. I've assumed that we are
' working in column E but adjust as appropriate
.FormulaR1C1 = "=IF(AND(HD!RC[-4]>0,ISBLANK(HD!RC[-1])),HD!RC[-4],""n/a"")"
' Take the formula we already have which is in R1C1 format, keep it in R1C1 format,
' change it from a relative reference based on cell r to an absolute reference
' and make that the new formula for this cell
.FormulaR1C1 = Application.ConvertFormula(.FormulaR1C1, xlR1C1, xlR1C1, xlAbsolute, r)
End With
' Move down one row
Set r = r.Offset(1, 0)
Loop Until r.Value = ""
End Sub
In case you aren't familiar with them. here are the references for Option Explicit and With...End With
You can do this without looping, Excel is smart enough to know you want incremental.
As an example do run this on a fresh sheet:
Sub ShowIncremental()
Range("A1:A10").Formula = "=Row(A1)"
Range("B1:B10").Formula = "=A1*2"
Range("C1:C10").Formula = "=sum(B$1:B1)"
End Sub
Notice the formulas created in A1:C10. Notice Excel incremented them even though the code didn't say to except in the case where we absoluted B$1.
I recommend you do something similar with your code to avoid looping, this will be much much faster.

Sum only visible cells in one ROW (not column)?

I have a row and I want to sum only visible cells, i know if it's a column I can use subtotal (109,range), but this one doesn't seem to work for cells in one row. Anyone knows how to sum only visible cells in a row?
Please click here for picture
If a VBA solution is okay, this will work:
Function sumVisible(rng As Range) As Double
Dim cel As Range
For Each cel In rng
If cel.EntireColumn.Hidden = False Then
sumVisible = sumVisible + cel.Value
End If
Next cel
End Function
Pretty straightforward - just checks if a cell in your range has a hidden column, if it's visible, sum it.
=sumVisible(D2:M2) is how you'd use it.
You can check the width of the cell.
=IF(CELL("width",A1)=0,"hidden","open")
you can then sum your cells as need it using IF and CELL
=IF(CELL("width",A1)=0,0,A1)
more info below:
Ignoring a hidden column in an excel sum formula
You can do this using a single worksheet formula alone, provided that none of the columns which remain unhidden will have a width of less than or equal to 0.5 (which, in practice, would be so narrow as to be virtually hidden in any case).
Assuming a range of A1:E1
=SUMPRODUCT(0+(CELL("width",OFFSET(A1,,N(INDEX(COLUMN(A1:E1)-MIN(COLUMN(A1:E1)),,))))>0),A1:E1)
Unfortunately this formula will not update automatically as changes regarding hiding/unhiding columns within the range are made. As such, it will be necessary to 'recommit' it each time you make changes in that respect; one way to do this is via going into the formula as if to edit it and then recommitting by pressing ENTER.
Perhaps of interest is this post.
Regards

Differences between A1 fixed referencing and formulaR1C1 relative positioning VBA

I have a macro that populates cells on a blank worksheet with values from another form worksheet using R1C1. The issue is that the position of the source data on the form worksheet changes as users add rows to input their data. The A1 solution to this would be to use a fix Cell column reference and allow the reference for the row to change 9ex. Cell=Sheet1!$A25, which could then change to Cell=Sheet1!$A26 as a row is added above. How can I make my FormulaR1C1 change in the same way as my A1?
Correct situation:
Cell A1=Sheet1!$F13
Therefore, ActiveCell.FormulaR1C1 = "=Sheet1!R[12]C6"
But when I add a row above F13:
Cell A1=Sheet1!$F14
But, ActiveCell.FormulaR1C1 = "=Sheet1!R[12]C6", Does not respond to the shift row down

Excel: delete entire row when other cell equals a defined value

I have seen (searched) similar examples, but not quite what I am looking for.
I have a Workbook in Excel that has several sheets, Sheet A and B. These sheets have a bunch of data, so in order to display the most significant data on Sheet B from Sheet A, I want to mirror only the rows that I want to specify depending on the cell values on SheetA....I need to delete entire rows in Sheet B depending on the value in Sheet A.
For instance, in Sheet A I have column X with 10 values (Yes/No), and I have linked the same data with formulas back to Sheet B. That is, that if in SheetA X1="Yes", then SheetB cell Y1="Done"...if SheetA X2="Yes", then SheetB cell Y2="Done"...if SheetA X3="No", then SheetB cell Y1="Missing"..and so on.
So I only want the rows in SheetB with cell values="Done" to be there and thus want rows with cell values="Missing" to be automatically deleted. In this fashion, I would be creating a table that only includes the rows with "Done" values for the specified cell.
I know there are macros in Excel, but I have never written code in VBA, and the language handlers and variables escapes me entirely.
Is there a way to write a macro that can be called with in a formula; that is, e.x) if(A10="Yes", "", delete row macro here)???
Thanks!
From the wording in your question it seems you want to create a function that can be used in a cell that will alter other cells. That cannot be done. The functions, when used in a formula, are limited to changing the cell itself, and not other cells.
More then one way to skin a cat. Like Abe said you can`t use formula to alter other cells. But you can use VBA. The below sub removes entire rows where the cell in range is equal to 1. But you can make it equal to whatever you want.
Sub DeleteRows()
Dim FoundCell As Range
Set FoundCell = Worksheets("SheetB").Range("YourRange").Find(what:=1)
Do Until FoundCell Is Nothing
FoundCell.EntireRow.Delete
Set FoundCell = Worksheets("SheetB").Range("YourRange").FindNext
Loop
End Sub
Of course this is extra work. What you should do instead of copying the data from A to B and then processing it, just copy the done cells from A to B.

Resources