I have an Excel file with multiple columns. If you observe the attached image the 1st column is coupons (repeated with different settlement dates). I need to write a macro which will loop through the file, and find one record for each coupon with the minimum date of all the dates that particular coupon has. For example, coupon 2 has 4 records in the attached image. I should delete three off them, and have only one record with the earliest date among those four.
Can someone please provide me an example?
One possibly is to use a temporary array formula. Assuming field Coupon is column B and Date is column C then in the next free column, say column N use {=IF(C2=MIN(IF($B:$B=B2,$C:$C)),TRUE,FALSE)}
Then use an advanced filter to filter on Coupon and TRUE in Column N. In this example I've set up the criteria and output from column Q
Eg VBA Code example
Sub test()
Dim rng As Range, strR1c1 As String
'identify minimum date using array formula
With Sheet1
.Range("N1").Value = "Temp Header"
'array formula = {=IF(C2=MIN(IF($B:$B=B2,$C:$C)),TRUE,FALSE)}
.Range("N2").FormulaArray = "=IF(RC[-11]=MIN(IF(C2=RC[-12],C3)),TRUE,FALSE)"
strR1c1 = .Range("N2").FormulaR1C1
Set rng = .Range("N2:N" & .Range("B" & .Rows.Count).End(xlUp).Row)
rng.Formula = strR1c1
rng.FormulaArray = rng.FormulaR1C1
'Advanced Filter criteria requirements to new range
.Range("B1:N11").AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=.Range( _
"Q1:AC2"), CopyToRange:=.Range("Q5:AC5"), Unique:=False
'tidy up - clear array formula
.Range("N:N").ClearContents
End With
End Sub
Related
I have this table, from a product structure, with parent, child, level and quantity information.
I need to consolidade the component quantity per position on the structure.
I am able to build the StructurePath data using VBA in a single loop.
The main assumption is StructurePath shall be unique across the entire table.
Question:
Is there a procedure to look for all values in StructurePath and sum up the total QTY-PER value, generating a data line in the Consolidated QTY column? After that, I can simply eliminate duplicates using the StructurePath column.
Exploded structure
I'm sorry, since I'm limited in English, I can't understand this sentence :
generating a data line in the Consolidated QTY column
Anyway, the code below will sum the value in column D (QTY-PER) based on each unique value of column H (StructurePath), and put the result in column F at the first row occurence of each unique value.
Sub test()
Set rg = Range("H2", Range("H" & Rows.Count).End(xlUp))
Set arr = CreateObject("scripting.dictionary")
For Each cell In rg: arr.Item(cell.Value) = 1: Next
For Each el In arr
Set c = rg.Find(el, After:=rg.Cells(rg.Rows.Count, rg.Columns.Count), lookat:=xlWhole)
c.Offset(0, -2).Value = Application.SumIf(rg, el, rg.Offset(0, -4))
Next
End Sub
Consider the following table:
I have a series of blank cells with missing data. From this missing data I only have the year in the next column. I need to fill any blank cells with a standard day/month of 30/06. The year of each cell however needs to be the year in the next column. The attached file shows how my data is arranged. So at cell B 2091, the date shall be 30/06/2011 while for cell B 2098 the date shall be 30/06/2018 and at cell B 2100 the date shall be 30/06/2008.
Filter on the blank cells in column B. Then, in the topmost cell (which I'll assume to be B1 but will likely be different), enter a formula similar to the following and fill down
=DATE(C1,6,30)
where the row number in C1 is the same as your first row of data.
You can achieve this with a helper column (any blank column in the same worksheet where you need the dates). In that column enter this formula in the first cell (here in row 2) and copy down.
=IF(ISBLANK(B2),DATE(C2,6,30),B2)
Then copy the Values from the helper column to the date column and delete the helper.
Below is a small macro that is doing the same job. It needs no helper column and over-writes your existing blanks. Before you run it make sure to check the values of the 2 constants at the top and the name of the worksheet (especially the latter!) against your requirements.
Sub WriteStandardDate()
'293
Const FirstDataRow As Long = 2 'change to suit
Const DateClm As Long = 2 'change to suit
' year column must be adjacent to DateClm
Dim R As Long
Dim Arr As Variant
Dim Rng As Range
With Worksheets("Sheet1") ' change name as required
Set Rng = .Range(.Cells(FirstDataRow, DateClm), _
.Cells(.Rows.Count, DateClm).End(xlUp)) _
.Resize(, 2)
Arr = Rng.Value
For R = 1 To UBound(Arr)
If IsEmpty(Arr(R, 1)) Then
Arr(R, 1) = DateSerial(Arr(R, 2), 6, 30)
End If
Next R
Rng.Value = Arr
End With
End Sub
Update: I used the formula suggested by Variatus: =IF(ISBLANK(B2),DATE(C2,6,30),B2) and worked fine through a helper column. There was no need to copy / paste the new dates into the Dates column. I just used the helper column as the new Dates column since full dates from the original column were not changed and got inserted in the helper column thanks to the IFBLANK portion of the formula. Thanks.
Input
I need Summary like below
I am looking for distinct no of account here instead of duplicate.
You can FILTER the original data and then count the number of unique instances.
Try =COUNT(UNIQUE(FILTER($A$2:$A$10, $B$2:$B$10=$D2)))
Here I assume that the original data is in cells A2:B10, and that the criteria for the filtering is in column D.
I have updated my answer to work for Office 2007 and mixed #Rory's comment to original post with my OFFSET part of my previous Office 365 solution.
Formula
Plase the following formula in E2:
=SUM(1/COUNTIFS(OFFSET($A$3,MATCH(D3,$A$3:$A$12,0)-1,1,COUNTIF($A$3:$A$12,D3),1),OFFSET($A$3,MATCH(D3,$A$3:$A$12,0)-1,1,COUNTIF($A$3:$A$12,D3),1)))
Explanation
The OFFSETpart provides a list of consecutive rows that feature the Acc No and belong to the same Br code. It uses MATCHto determine the first occurance of the given Br code. As the anchor cell for the formula is the cell with the first content ($A$3), I subtract 1 from the MATCH result. To determine the height, I use a COUNTIF statement, that counts how many rows feature the current Br code.
The cell range provided by OFFSET is then used as input for #Rory's COUNTIFS solution.
The text and non-text (numeric) unique and distinct values in the column are quickly listed separately using VBA macro.
enter image description here
Sub GetCountDistinctValues()
Dim sayi As Long, rang As Range
With CreateObject("Scripting.Dictionary")
For Each rang In Range("A2:A" & Cells(Rows.Count, "A").End(xlUp).Row)
If rang <> Empty Then
If Not .Exists(rang.Value) Then
.Add rang.Value, Nothing
If IsNumeric(rang.Value) Then sayi = sayi + 1
End If
End If
Next
Range("C2").Value = .Count - sayi
Range("C3").Value = sayi
End With
End Sub
Source : Find count of unique-distinct values
Hi'm new to VBA and i'm trying to work on a QA report(call audit) that will automatically calculate values based on the data of another worksheet. I have 2 Sheets: Elements which contains the data, and AutoMacro which shows the number of cells that meets a specific criteria.
The Elements sheet has columns named Element and Rate, and WeekNumber. I made a code that will list all distinct week numbers to the "AM" column of the Automacro Sheet. Now, i want to count how many calls got a rate of 'Developing'(which is in column Rate of the Elements sheet) in Compassion(which is in column Element of the Elements sheet) on a specific week(AM column in the AutoMacro Sheet)
this code works fine:
CompDevCount = Application.WorksheetFunction.CountIfs( _
Sheets("Elements").Range("f2:F1048576"), "Compassion", _
Sheets("Elements").Range("G2:G1048576"),"Developing", _
Sheets("Elements").Range("C2:C1048576"), "4")
however, instead of putting a fixed value in the last criterion which is the weeknumber, i want my code to get the value of the corresponding cell in column AM(if macro is calculating values for row2 in the AutoMacro sheet, it should change the "4" to whatever value AM2 has) and i cant figure out how to do it.
any help is greatly appreciated
here's a link to my sample file:
https://drive.google.com/file/d/1ZXuMsQv_mzvycPXnGCGY7bUL6-gWBrBr/view?usp=sharing
Try the code bellow:
Sub LetsCount()
Dim lastElementsRowIndex As Long
Dim wsElements As Worksheet
Dim wsAutoMacro As Worksheet
Dim elementRange As Range
Dim rateRange As Range
Dim weekRange As Range
Dim i As Long
Dim weekNumber As Integer
Set wsElements = Sheets("Elements")
Set wsAutoMacro = Sheets("AutoMacro")
'//Get the index of the last filled row based on column A (Analyst)
lastElementsRowIndex = wsElements.Cells(Rows.Count, "A").End(xlUp).Row
'//Get ranges
Set elementRange = wsElements.Range("F2:F" & lastElementsRowIndex)
Set rateRange = wsElements.Range("G2:G" & lastElementsRowIndex)
Set weekRange = wsElements.Range("C2:C" & lastElementsRowIndex)
'//Looping through all filled rows in the AutoMacro sheet
For i = 2 To wsAutoMacro.Cells(Rows.Count, "A").End(xlUp).Row
'//Get week number from cell in column "AM"
weekNumber = wsAutoMacro.Cells(i, "AM").Value
'//Get the number of calls with: Rate = 'Developing', Element = 'Compassion' and Week Number = weekNumber
CompDevCount = Application.WorksheetFunction.CountIfs( _
elementRange, "Compassion", _
rateRange, "Developing", _
weekRange, weekNumber)
'//Insert the value in the corresponding cell of the AN column (column that I adopted to put the value)
wsAutoMacro.Cells(i, "AN").Value = CompDevCount
Next
End Sub
I'm trying to create a macro that will compare the first 4 characters of one column to the first 4 characters of another column in the same row and then mark that row as either Match or No Match.
I did some research and found an Excel formula (=IF(ISNA(MATCH(LEFT(A2,4)&"*",B2:B2,0)),"No Match","Match") which works but I'm not sure how to convert this to VBA. The spreadsheets I'm working with can vary in row length from day to day but they would always have the same number of columns. So I need to be able to: compare column C to column F and write the Match / No Match outcome to column G regardless of the number of rows on the spreadsheet.
Here is an example of the spreadsheet I'm working with that shows the outcome of using the Excel formula.
Any help / suggestions you can provide would be appreciated.
]1
You can use simplified formula and convert it to values if needed (works for active sheet).
Sub CompareLeft()
Dim LRow As Long
LRow = Cells(Rows.Count, "A").End(xlUp).Row
With Range("c2:c" & LRow) '<-- Adjust result column
.FormulaR1C1 = "=IF(LEFT(RC1,4)=LEFT(RC2,4),""Match"",""No Match"")"
.Value = .Value '<-- Optional - convert formula to values
End With
End Sub