I am creating a report in Excel and I would like VBA to format the row height based upon the value in column K. For example, if cell K17 = 11.25, I want row 17 to be 11.25. Cell k18 = 21.75 so row 18 =21.75.
I need vba to change every row from 17-400.
This should be relatively simple but I can't seem to come up with the correct coding.
Since this is an easy one, I went ahead and provided the answer for you:
Sub RowHeight()
Dim ws as Worksheet
Set ws = Sheets("mySheet") 'replace with your sheet name
Dim rCell as Range
For each rCell in ws.Range("K17:K400")
rCell.EntireRow.RowHeight = rCell.Value
Next
End Sub
Related
Concept:
Entire Rows are deleted through a macro based off parameters which are represented as an excel formula by the user. The idea here is that a user can use Boolean formulas that they're already familiar with to evaluate values in a range (read the "Process" below for further clarification).
Process:
A user clicks on a button which shows a form. This form contains two input fields (or parameters); "Column" and "Formula". The "Column" is the range for which the macro will be cycling through (let's say $A:$A). The "Formula" is an Excel based formula represented as such, in the user parameter field ie =OR(A1="X",A1="Y"). However, I've instructed the user to replace any instance of A1 with rng. I've requested the user to do this because the idea here is that I would replace rng with a changing variable in VBA that cycles through all the cells specified in the "Column" parameter.
Problem:
I'm not aware of any way to replace the rng representation within the Excel formula with a range variable in VBA.
Update 4-7-17
Thank you all for your responses but I'm pretty certain my problem is getting lost in translation. I'm aware this is my fault, since I didn't provide any code for analysis. Unfortunately, therein lies the issue. I don't know what to write. I'm going to do my best to write some code (that I know is wrong) which will hopefully convey what I'm trying to accomplish.
Sample Code 4-7-17
Sub SampleCode()
Dim wRng As Range
Set wRng = Range("A1:A26") 'Let's assume that the values in this range are the
' letters of the alphabet
Dim Counter As Integer
'Cell "B2" will contain a formula that the user has entered
'which is: =OR(rng="X",rng="M")
'Obviously the formula returns an error in excel (#NAME? to be
'exact) but that's understood.
Dim wFormula As String
wFormula = Range("B2").Formula
Dim rng As Range 'This variable "rng" is what is represented in the
'formula that was written in Range("B2")
'*** This is where I get stuck. I know I'm missing code here to
'be able to proceed with my routine below.
'code
'code
'code
Counter = wRng.Rows.Count
For i = 1 To wRng.Rows.Count
Set rng = Cells(Counter, 1)
If wFormula = True Then
rng.EntireRow.Delete
End If
Counter = Counter - 1
Next i
'The ending result should be that row 24 was deleted because it contained
'the letter "X" and row 13 was deleted because it contained the letter "M"
'
'The objective of this code is to use any Excel formula which evaluates out
'to a True or False value.
End Sub
Hey Jon first you need to declare a Variable of relevant data type, then pass value from Range & finally use where you wish to, like,
Dim Src As Variant
Src= Sheets( "Sheet3" ).Range( "A2:A9" ).Value
Hey John this code will help you to get the solution,
Public Sub ProcessData()
Const TEST_COLUMN As String = "A"
Dim Lastrow As Long Dim i As Long
Application.ScreenUpdating = False
With ActiveSheet
Lastrow = .Cells(.Rows.Count, TEST_COLUMN).End(xlUp).Row
For i = Lastrow To 1 Step -1
If Cells(i, TEST_COLUMN).Value2 Like "AU" Or _ Cells(i, TEST_COLUMN).Value2 Like "AZ" Then
.Rows(i).Delete
End If
Next i
End With
Application.ScreenUpdating = True
End Sub
I have a range of cells B2:AB40.
If every cell in each row within the the range is blank (by which I mean no text or numbers, just colour fill and border formatting), I want to hide the whole of the row using a macro.
e.g.
If every cell in the range B2:AB2 is blank then hide all of row 2.
If every cell in the range B3:AB3 is blank then hide all of row 3
If every cell in the range B4:AB4 is blank then hide all of row 4..etc etc etc
Up to and including row 40.
N.B. Each cell in column A and AC in every row adjacent to the specified range will always have text (someone's name and a formula result respectively) and this cannot be changed.
I have seen various ways of doing this based on a single cell but cannot seem to adapt them for my purposes.
Any help is appreciated.
Consider:
Sub RowHider()
Dim I As Long, wf As WorksheetFunction
Set wf = Application.WorksheetFunction
For I = 2 To 40
If wf.CountA(Range("B" & I & ":AB" & I)) = 0 Then
Rows(I).Hidden = True
Else
Rows(I).Hidden = False
End If
Next I
End Sub
Note the usage of a worksheet function in VBA.
Try this
Sub HideRangeIfEmpty()
If Application.WorksheetFunction.CountA(Range("b2:AB2")) = 0 Then
Range("b2:AB2").EntireRow.Hidden = True
End If
End Sub
I was assisted with the code below which is great, however it brings through/selects the cell address as per the previous sheet, please can you provide code for a dynamic range so it brings through/selects cells based upon current selection in the new sheet rather than cell address
Sub MatchRange()
Dim ady As String
ady = Selection.Address
Sheets("Sheet2").Select
Range(ady).Select
End Sub
Link to where previous code was sourced:
Match/resize new range based on another sheets selection
Sorry for being vague, so lets say in sheet a I have range a1:b50 selected, I want to match the selection size in sheet b. So in this situation it would be c51:d100.
The question is a bit vague, but I'll give an example on a method of selecting an equivalent sized range based on the selected cells in each sheet. Please try to amend to meet your needs and let us know if you have more specific questions.
Sub MatchSelectionArea()
Dim rng As Range
Dim nRows As Long
Dim nCols As Long
Set rng = Selection
nRows = rng.Rows.Count
nCols = rng.Columns.Count
Sheets("Sheet2").Activate
ActiveCell.Resize(nRows, nCols).Select
End Sub
When your code reads the Selection.Address you should prefix it with the sheet that you want to use for the source. So:
Sub MatchRange()
Dim ady As String
ady = Sheets("sheet_name").Selection.Address
Sheets("Sheet2").Select
Range(ady).Select
End Sub
I'm not sure of what you need but this is an example to get a range of the same dimensions of another range (hope it helps)
Set ady = Range("A1:C3")
RngNumCol = ady.Columns.Count
RngNumRow = ady.Rows.Count
NewRngStart = ActiveCell.Address 'Here the starting cell of the new range
NewRngEnd = Range(NewRngStart).Offset(RngNumRow - 1, RngNumCol - 1).Address
Set NewRng = Range(NewRngStart, NewRngEnd)
'Test
For Each mycell In NewRng.Cells
mycell .Value = "Test"
Next
I'm trying to create a yearly summary for some of our transfers. Essentially, I have 12 sheets, one for each month of the year, and each entry is given one of four specific "Transfer Rationales" in column L. I need to be able to create a worksheet that gives me a running year-to-date summary based on each transfer rationale.
So say, for example, the transfer rationale I'm looking at is called "Incorrectly Assigned" - I think need to have the summary page show columns G-K of each row where column L is "Incorrectly Assigned" from all twelve month sheets.
I've been looking at VBA code and trying to tweak some to work, but I could use some help!
EDIT:
Obviously it's not working as I need or I wouldn't be here, but I don't have much knowledge about VBA. I have something here where the code is grabbing the entries where column L met the criteria, but it was
a) copying all the columns, and I only need G-K to paste, and
b) was putting the copied rows all in one row in the summary tab, so I could see the data for a split second, and then it would overwrite with the next line and so on until it finally settled on the last entry found.
SECOND EDIT:
So I have a code that now (mostly) works, I've pasted it below and deleted the old code above.
Private Sub CommandButton1_Click()
Dim WkSht As Worksheet
Dim r As Integer
Dim i As Integer
i = 1
For Each WkSht In ThisWorkbook.Worksheets
i = i + 1
If WkSht.Name <> "Incorrectly Assigned" Then
For r = 1 To 1000
If WkSht.Range("L" & r).Value = Sheets("Incorrectly Assigned").Range("A1").Value Then
WkSht.Range("E:L").Rows(r & ":" & r).Copy
Sheets("Incorrectly Assigned").Range("E:L").End(xlUp).Offset(i, 0).PasteSpecial Paste:=xlPasteValues
End If
Next r
End If
Next WkSht
End Sub
The problem now is that it is only grabbing the last match from each worksheet - so say January has four matching entries, it's only pasting the fourth entry, then the next row down it'll paste the last entry from February etc. and then if there's an entry in say November that matches, it'll be pasted in the 11th row from the beginning, rather than each entry being pasted one after another.
Better to create a sub-routine that you call from your "CommandButton1". Then you can call the procedure from more than one location. You can also generalize it by using an input parameter 'transferID' which defines the summary you want.
Private Sub CommandButton1_Click()
Call PrintSummary("Incorrectly Assigned")
End Sub
It will likely need some tweaking to get it how you want, but this should give you some ideas to get you started:
Sub PrintSummary(transferID As String)
Dim ws As Excel.Worksheet
Dim wso As Excel.Worksheet
Dim lrow As Long
Dim rng As Excel.Range
Dim rngo As Excel.Range
Dim cell As Excel.Range
Dim colH As Variant
Dim i As Integer
'// Define columns for output
colH = Array("G", "H", "I", "J", "K")
'// Check for summary sheet (for output)
On Error Resume Next
Set wso = ThisWorkbook.Worksheets("Summary")
On Error GoTo 0
If wso Is Nothing Then
'// Summary worksheet does not exist :/
Exit Sub
Else '// format worksheet for output
'// for example...
wso.Cells.Delete Shift:=xlUp
Set rngo = wso.Range("A1") '// define output start
Set wso = Nothing
End If
'// Loop through worksheets
For Each ws In ThisWorkbook.Worksheets
'// Check for valid worksheet name
Select Case VBA.UCase(ws.Name)
Case "JAN", "FEB" '// and so forth...
Set rng = ws.Range("L1")
Set rng = ws.Range(rng, ws.Cells(Rows.Count, rng.Column).End(xlUp))
For Each cell In rng
If (VBA.UCase(cell.Text) = VBA.UCase(transferID)) Then
'// Print meta data
rngo.Offset(lrow, 0).Value = ws.Name
rngo.Offset(lrow, 1).Value = transferID
'// Print values
For i = 0 To UBound(colH)
rngo.Offset(lrow, i + 2).Value = ws.Cells(cell.Row, VBA.CStr(colH(i))).Value
Next i
'// Update counter
lrow = lrow + 1
End If
Next cell
Case Else
'// Not a month? do nothing
End Select
Next ws
End Sub
You do not need VBA - just refence the cell in the other tab:
SheetName!CellAddress
Precede the cell address with the worksheet name, and follow it with an exclamation point.
If you need VBA, then I have understood your question incorrectly.
EDIT:
Lets start with problem B:
was putting the copied rows all in one row in the summary tab
Lets look at the code you use to paste values:
Sheets("Summary").Range("A65536").End(xlUp).Offset(1).PasteSpecial Paste:=xlPasteValues
Here you always paste everyting in the same place, in cell A65536 which you offset by one. On every iteration of your loop, the values will be at the same place. Change the Offset(1) to
Offset(0, r)
Now on every iteration you will paste on a different row, because r will be 1, 2, ..., 1000. See MSDN for documentation on Offset. Select a values that accomplished a paste the way you need.
Lets go to the next question:
a) it was copying all the columns
I will edit once the first part works as it should for you.
After I have selected a range containing numerical values, I want to, via VBA, input a =SUM formula at the bottom of each column, i.e. on the row after the last selected row. For each column it should sum all of the values in the corresponding column of the entire selection.
How can I do this?
Right now, I am using the code given by the macro recorder: ActiveCell.FormulaR1C1 = "=SUM(R[-10]C:R[-1]C)". The problem is when my range gets bigger than 10 rows it will not take the rows above the bottom 10 into consideration.
Here is a simple non-VBA Approach.
Select the cells where you want the sum and press Alt-=.
SNAPSHOT
And here is a one-line VBA code that does the same thing.
Sub AutoSum()
'~~> After you select your range
Application.CommandBars.ExecuteMso ("AutoSum")
End Sub
This works:
Sub MakeSums()
Dim source As Range
Dim iCol As Long
Dim nCol As Long
Dim nRow As Long
Set source = Selection
nCol = source.Columns.Count
nRow = source.Rows.Count
For iCol = 1 To nCol
With source.Columns(iCol).Rows(nRow).Offset(1, 0)
.FormulaR1C1 = "=SUM(R[-" & nRow & "]C:R[-1]C)"
.Font.Bold = True
End With
Next iCol
End Sub
Example:
You could also do something like this without VBA:
=SUM(OFFSET(INDIRECT(CELL("address")),1-ROW(),0,ROW()-1,1))
This will sum all cells above the cell in which the formula exists.
Here is a quick trick to sum selected cells in vba code.
Private Sub Sum_Click()
MsgBox Application.Sum(Range(Selection.Address))
End Sub
This is what I was searching for when I landed on this thread so maybe it will help someone.