Relatively new to VBA and I have a specific scenario that I need help with. I track daily production numbers for my company and, at the end of each "run" of a product, I have various totals and averages I need to calculate. The issue I'm encountering is that each run is broken out into daily performance and not all runs are the same amount of days.
Here is an example of the layout:
Example Layout
The green row is the total row. Order, Product, and Description are all just equal to the cell above. The rest are sums of the above cells AFTER the last total row.
So far, I got it to insert a row where the active cell is, copy the order, product, and description cells. I also wrote a section to count the number of active days and store it as an integer, "ncount", using CountIf based on the order number, since those are unique to each run. Here is what I have so far:
Sub Total()
' Inserts row and sets color
ActiveCell.EntireRow.Insert
ActiveCell.EntireRow.Interior.ColorIndex = 43
' Sets Order number value
ActiveCell.Value = ActiveCell.Offset(-1)
' Count number of active days
Dim nCount As Integer
Dim order As Long
order = ActiveCell.Value
nCount = Application.WorksheetFunction.CountIf(Range("D:D"), order) - 1
'Sets Product value
ActiveCell.Offset(0, 1).Select
ActiveCell.Value = ActiveCell.Offset(-1)
End Sub
I'm sure that's not the most efficient way to go about those tasks, but I'm still new to VBA and am open to feedback.
What I'm running into is how to successfully sum a range based on the active cell and a count of days running (nCount). I'm thinking I could store the order number as a variable and use it in SumIf statements, but I'm not sure how to do that without the SumIf cell referencing itself.
Can anyone offer some insight?
Thanks!
Related
I am trying to shade every other group of visiable cells.
Each row of my data contains information on a given Order and there can be multiple rows for each order, e.g. Order 1 many have 3 rows while order 2 may have 1 row, etc. The data is sorted by Order Number so all rows for a given order are contiguous.
I have shaded each group vis a helper column (AS) containing the following formula: =IF(ROW()=2,TRUE,IF(A2=A1,AS1,NOT(AS1)))
which results in every other Order group being either TRUE or False. Then I use conditional formatting to shade every "TRUE" row.
This works until I begin filtering my data and then I can end up with either two shaded or to unshaded groups next to each other.
I think what I'm looking for is a VBA function that will compare a cell with previous VISIBLE cell and will return TRUE or FALSE if the match or not.
Any help will be much appreciated.
you can use this code that shades every other row
Sub ShadeThem()
Dim okShade As Boolean
Dim r As Range
For Each r In Range("A1", Cells(Rows.Count, "A").End(xlUp)).SpecialCells(xlCellTypeVisible)
If okShade Then
r.EntireRow.Interior.Color = vbRed
okShade = False
Else
okShade = True
End If
Next
End Sub
I assumed your filtered data affect column A from row 1 downwards
Did they not, just change "A1" and Cells(Rows.Count, "A") to affect the needed column
In order to have it run at every new filtering, you could:
add a helper cell which counts the number of visible rows
=SUBTOTAL(103;A1:A1000)
this will trigger the Worksheet_Calculate event at every filtering
add the Worksheet_Calculate event hander in the relevant sheet code pane
Private Sub Worksheet_Calculate()
ShadeThem
End Sub
As I said in the comments, there's almost surely a better way to do what you're trying as a whole with your spreadsheet (a table!). However, if you really wanted a VBA custom formula to test if a cell is hidden or not you could use this...
Function isHiddenRow(aRange As Range) As Boolean
isHiddenRow = aRange.EntireRow.Hidden
End Function
There's some possibilities this formula assumes:
Only one cell.
Filtering impact of recalculations.
I'm trying to avoid copy and paste in order to dramatically speed up a Macro (previously taking two minutes to run). I am trying to reference four entire columns in Sheetx(A,B,J,L) and have them display in sheety(A6,B6,C6,D6).
I have tried a number of variations of
Sheets("Sheety").Range("A6:A,B6:B,C6:C, D6:D").Value = Sheets("Sheetx").Range("A:A, B:B, J:J, L:L").Value
Also, for sheets("sheety") I tend towards Active.Sheet or Sheets(B) as I have used the index number for the sheet ie
For B = 31
31 being the index number for the real sheet.
I have been searching for answers for the last hour. Can anyone help?
Tell me if something like this:
Sub Testy3()
Dim N As Long
N = Sheets("Sheet1").Cells(Rows.Count, "A").End(xlUp).Row
Sheets("Sheet1").Range("A1:A" & N).Copy Sheets("Sheet2").Range("A6")
End Sub
works for you.
If all the columns in Sheet1 have the same number of rows, then you don't need to re-calculate N for each column.
I am working on a model that requires me to sort data in a range by date, before copying the data into a different template on another sheet. Every row has a formula that pulls data from Bloomberg, so even if the cell looks empty, excel recognizes that there is content in the cell. Sorting the date column as it is does not work, as excel wont recognize the data that Bloomberg pulls as a date, so it would be sorted from A to Z, which scrambles the dates instead.
To work around this, I inserted and adjacent column with the formula (using cell A1 as an example) "=(A1+0)" that then allows the column to be sorted from new to old. The problem here is that if cell A1 does not display a date (in other words, it appears empty yet the cell contains a formula that leaves the cell looking empty if no date is pulled) it returns a #VALUE! error and sorting new to old would put the errors at the top (Thank you Excel for this fantastic feature, btw).
To work around this new issue, I replaced the above formula in the cell with "=IFERROR(A1+0,1)" which gives me the date 1/1/1900. Fine, now the data is sorted in the manner I want it, but I have a bunch of ancient dates that just make my end product look ugly.
I have two questions, first; how can I use VBA to delete the data in the cells where the date equals 1 (which shows the date 1/1/1900), and only those cells? Or, alternatively, only copying the rows above the cell that contains 1/1/1900. This is a relatively small amount of cells that would be affected by this, 40 at most.
Second; is there a different way of sorting the data using VBA that I am missing, that might be more efficient?
Try this macro, I tried to test it with as many anomalies as possible.
Sub SortByDateColumnH()
Dim r As Range: Set r = Sheet1.Range("B3:P40")
Dim cel As Range
For Each cel In r.Columns(7).Cells
If IsError(cel.Value) Then
cel.Value = 0
ElseIf Not IsDate(cel.Value) Then
cel.Value = 0
Else
cel.Value = CLng(cel.Value)
End If
Next
r.Columns(7).NumberFormat = "0"
r.Sort Key1:=r.Cells(1, 7), Order1:=xlDescending, Header:=xlNo
For Each cel In r.Columns(7).Cells
If cel.Value < 100 Then cel.ClearContents
Next
r.Columns(7).NumberFormat = "m/d/yyyy" '<-- set the format to your preference
'r.Copy Destination:=someDestination ' you can copy the range by code if needed
End Sub
So I've searched everywhere... I have an office 2007 excel spreadsheet with two pages, one labeled "i" and the other "t." I need to display selective rows (those rows that have a value in column A--not all do) from "i" in "t." I also need the rows in the "t" page to be in numerical order. I figured out how to do it across all rows, but not how to selectively add rows with values only in column A. Further, when I add new rows to "i," "t" doesn't automatically update. Any advice on how to accomplish this would be of immense help!
I have access to office 2010. I don't know if that makes the coding easier?
Thank you!
Jason
You could try a user-defined function like this:
Function NonBlank(Selection As Range, Index As Integer) As Variant
Dim Count As Integer
Count = 0
For Each cell In Selection
If Len(cell.Value) > 0 Then Count = Count + 1
If Index = Count Then
NonBlank = cell.Value
Exit For
End If
Next
End Function
Then on Sheet t, you can put =NonBlank(i!A:A,ROW(A1)) in the first cell where you want the first non-blank value of Sheet i, and then copy the formulas down.
my problem is:
I have a matrix in excel then a function (repeated N times) that extract from this matrix a random number.
This happen everytime i hit F9 or everytime something change in the sheet.
After this i have another cell with a sum of all then numbers extracted. I would like to keep track of the change of this last cell in a linear chart to see how it goes on.
Thank you so much in advance
Solution 1: formulas
if you want to repeat T times, just instead of only 1 series of N number create a matrix of N by T. Then ad 1 last row (or column) under (or next to) the N functions for all T which contains the sum.
Now relate a chart to this last row (or column).
Solution 2: VBA
Create a piece of code that loops T times and copies the value of the cell with the sum into the next empty cell in a designate part of your excel workbook.
Sub aaa
dim i as Long
dim T as Long
T = 1000
For i = 1 to T
Range("rSum").Copy
Cells(rows.count,1).offset(xlUp)).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
Next i
End Sub