Total number of times a value is greater than the values in a column - powerbi-desktop

I am trying to determine the total number of times a value within "Current Actual" is greater than the values in column "Original Baseline".
Column "C" within the image below, is the result I am trying to achieve.
The first value in column "Current Actual" is only greater than 1 value in column "Original Baseline". The second value in column "Current Actual" is greater than two values in column "Original Baseline".
The only solution I found is to add an index column and create an if statement to reference the previous row using the column index, if there is an error. Is there a more efficient way to achieve the result?
= Table.AddColumn(#"Changed Type2", "C", each if [Current Actual] > [Original Baseline] then [Index] else if [Current Actual] > #"Changed Type2"{[Index]-2}[Original Baseline] then [Index]-1 else if [Current Actual] > #"Changed Type2"{[Index]-3}[Original Baseline] then [Index]-2 else if [Current Actual] > #"Changed Type2"{[Index]-4}[Original Baseline] then [Index]-3 else if [Current Actual] > #"Changed Type2"{[Index]-5}[Original Baseline] then [Index]-4 else if [Current Actual] > #"Changed Type2"{[Index]-6}[Original Baseline] then [Index]-5 else if [Current Actual] > #"Changed Type2"{[Index]-7}[Original Baseline] then [Index]-6 else 0)

Related

How to count the number of cells in a row that have a number greater than 7 as part of the text such as "8 days"

I have a spreadsheet that has several columns. I'm only going to show data from 2 of them here, because they're the 2 that I'm dealing with in this problem.
The first column is IP Addresses. The second column is how long ago the last response was or the last response date:
Address
Last Response
10.1.1.109
10/17/2022
10.1.1.113
10/17/2022
10.1.1.137
10/17/2022
10.1.1.188
4 days
10.1.1.199
10/17/2022
10.1.21.5
10/17/2022
10.1.21.50
45 days
10.1.50.41
10/17/2022
10.1.50.71
10/17/2022
10.1.88.10
10/17/2022
10.1.88.249
6 days
10.16.6.190
4 days
10.64.0.76
28 days
10.64.3.48
45 days
What I need to do is to get a few counts worked out. I want to know how many from each IP subnet have
A response older than 1 week
A Response older then 1 month.
In the sample data you can see 3 IP subnets: 10.4, 10.16, and 10.64. I am expecting to get results like:
IP Subnet
> Week
> Month
10.1
9
1
10.16
0
0
10.64
2
1
I have a formula for the "> Week", but I don't like it. I am not able to figure out how to count based on the number at the beginning of the text in that column. I tried a formula like this:
=COUNTIFS(AllIPAddresses,"10.1.*",AllResponses, NUMBERVALUE(LEFT(AllResponses, FIND(" ",AllResponses)))&">7")
Obviously this doesn't work. It gives me a column full of 0's.
What I have working for the "> Week" column:
=COUNTIFS(AllIPAddresses,CONCAT(A2,"*"),AllResponses,"<>7 days",AllResponses,"<>6 days",AllResponses,"<>5 days",AllResponses,"<>4 days",AllResponses,"<>3 days",AllResponses,"<>2 days",AllResponses,"<>Today",AllResponses,"<>Yesterday")
But like I said, I don't like it as it is just looking at the column and not counting 8 of the options. I would prefer if I could have a way to get it to look at the column and count those whose number of days is > 7. Something simple would be great, but something that is shorter and/or simpler than what I have I'll take. And I cannot reuse that effectively for the "> month" result because then I'd have to list some 30 different options that I don't want to count.
It would be better to have it look for the 1 option that I do want.
I'm hoping for something like:
First COUNTIFS counts all the text that have a number > 7
Second COUNTIFS counts all the dates that are more than 7 days before today
=COUNTIFS(AllIPAddresses, CONCAT(A2,"*"),AllResponses, LEFT(AllResponse,2)&">7")+COUNTIFS(AllIPAddresses, CONCAT(A2,"*"),AllResponses,"<"&today()-7)
And then I can reuse this for the "> month" by changing the 7 to a 30.
Though I know this formula doesn't work.
Any assistance with this problem would be appreciated!
Some Notes about my formulas
For ease of use I have named ranges:
AllIPAddresses = A2:A700
AllResponses = B2:B700
(in my formula for > week) A2 is referring to the "10.1." so that the CONCAT will give the result of "10.1.*" to the COUNTIFS
EDIT
I have added an answer that explains why I chose the solution that I did and how I had to tweak the answers I received to make them work for my specific scenario.
This could be accomplished using:
=LET(data,A2:B15,
_d1,INDEX(data,,1),
_d2,INDEX(data,,2),
lr,TODAY()-IF(ISNUMBER(_d2),_d2,TODAY()-(LEFT(_d2,LEN(_d2)-LEN(" days")))),
lft,TEXTBEFORE(_d1,".",2),
unq,UNIQUE(lft),
sq,SEQUENCE(COUNTA(lft),,1,0),
mm,--(TRANSPOSE(unq)=lft),
wk,MMULT(--(TRANSPOSE(lft)=unq)*TRANSPOSE(lr>7),sq),
mn,MMULT(--(TRANSPOSE(lft)=unq)*TRANSPOSE(lr>30),sq),
stack,HSTACK(unq,wk,mn),
VSTACK({"IP Subnet","> Week","> Month"},stack))
lft uses TEXTBEFORE to get the first 2 sections of the IP address.
lr calculates the number of days of the last response compared to today.
unq is the unique values of lft (IP subnet).
wk uses MMULT to calculate the conditional count of unique IP subnet values where lr is greater than 7.
mn is the same as wk, but where lr is greater than 30.
Perhaps you could try:
• Formula used in cell D2
=LET(_ipaddress,TEXTBEFORE(Address,".",2),
_days,IFERROR(TODAY()-ISNUMBER(Last_Response)*Last_Response,
SUBSTITUTE(Last_Response," days","")+0),
_uip,UNIQUE(_ipaddress),
_week,BYROW(_uip,LAMBDA(x,SUM(--(x=_ipaddress)*(_days>7)))),
_month,BYROW(_uip,LAMBDA(x,SUM(--(x=_ipaddress)*(_days>30)))),
VSTACK({"IP Subnet","> Week","> Month"},HSTACK(_uip,_week,_month)))
Explanations of each named variables used to make the calculations:
• Address --> is a defined name range and refers to
=$A$2:$A$15
• Last_Response --> is a defined name range and refers to
=$B$2:$B$15
• _ipaddress --> extracts the IP Subnet using TEXTBEFORE()
TEXTBEFORE(Address,".",2)
• _days checks whether the range is a number or text, since in Excel dates are stored as a number, we are using ISNUMBER() to check which returns TRUE and FALSE for text values,
So that said, the first part of the IFERROR() checks and returns the number of days,
TODAY()-ISNUMBER(Last_Response)*Last_Response
While the second part which is a text value, we are only substituting the " days" with empty and converting it to a number as well.
SUBSTITUTE(Last_Response," days","")+0
=IFERROR(TODAY()-ISNUMBER(Last_Response)*Last_Response,
SUBSTITUTE(Last_Response," days","")+0)
• _uip --> This gives us the Unique IP SUBNET
UNIQUE(_ipaddress)
• _week --> this gives us the count for each unique values row wise and returns as an array of output, for those days which are greater than 7 days.
BYROW(_uip,LAMBDA(x,SUM(--(x=_ipaddress)*(_days>7))))
• _month --> while this gives us the count for each unique values row wise and returns as an array of output, for those days which are greater than 30 days.
BYROW(_uip,LAMBDA(x,SUM(--(x=_ipaddress)*(_days>30))))
• Last but not least, we are packing all the variables that are needed to show as an output with in an HSTACK()
HSTACK(_uip,_week,_month)
To make it look good with a proper header we are wrapping it within an VSTACK(), along with the headers, [1x3] array
Well, you can also perform such tasks quite easily using Power Query as well:
To accomplish this task using Power Query please follow the steps,
• Select some cell in your Data Table,
• Data Tab => Get&Transform => From Table/Range,
• When the PQ Editor opens: Home => Advanced Editor,
• Make note of all the 2 Tables Names,
• Paste the M Code below in place of what you see.
• And refer the notes
let
//IPAddresstbl Uploaded in PQ Editor,
Source = Excel.CurrentWorkbook(){[Name="IPAddresstbl"]}[Content],
//Date Type Changed
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Last Response", type text}}),
//Extracting the IP SUBNET
#"Extracted Text Before Delimiter" = Table.TransformColumns(#"Changed Type", {{"Address", each Text.BeforeDelimiter(_, ".", 1), type text}}),
//Replacing " days" in last response column
#"Replaced Value" = Table.ReplaceValue(#"Extracted Text Before Delimiter"," days","",Replacer.ReplaceText,{"Last Response"}),
//Removing " 12:00:00 AM" from Date Time since we changed the data type of lastresponse as text
#"Extracted Text Before Delimiter1" = Table.TransformColumns(#"Replaced Value", {{"Last Response", each Text.BeforeDelimiter(_, " 12:00:00 AM"), type text}}),
//Adding custom column return the numbers of days
#"Added Custom" = Table.AddColumn(#"Extracted Text Before Delimiter1", "Custom", each if Value.Is(Value.FromText([Last Response]), type number) then [Last Response] else Date.From(DateTime.LocalNow()) - Value.FromText([Last Response])),
//Changing the data type of the custom column to ensure they are numbers
#"Changed Type1" = Table.TransformColumnTypes(#"Added Custom",{{"Custom", Int64.Type}}),
//Removing unwanted columns
#"Removed Columns" = Table.RemoveColumns(#"Changed Type1",{"Last Response"}),
//Returning 1 for those days which are more than 7 else returning as 0
#"Added Conditional Column" = Table.AddColumn(#"Removed Columns", "> Week", each if [Custom] > 7 then 1 else 0),
//Returning 1 for those days which are more than 30 else returning as 0
#"Added Conditional Column1" = Table.AddColumn(#"Added Conditional Column", "> Month", each if [Custom] > 30 then 1 else 0),
//Grouping by each IP Address
#"Grouped Rows" = Table.Group(#"Added Conditional Column1", {"Address"}, {{"> Week", each List.Sum([#"> Week"]), type nullable number}, {"> Month", each List.Sum([#"> Month"]), type nullable number}}),
//Renamed the IP Address Column
#"Renamed Columns" = Table.RenameColumns(#"Grouped Rows",{{"Address", "IP SUBNET"}})
in
#"Renamed Columns"
• Change the Table name as SUBNETtbl before importing it back into Excel.
• When importing, you can either select Existing Sheet with the cell reference you want to place the table or you can simply click on NewSheet
Answer chosen information
I choose the answer by P.b because I was able to get it to work for me first. I did have to tweak the code he provided like this:
=LET(data,AllData, _d1,INDEX(data,,1)
, _d2, INDEX(data,,4)
, lr, TODAY()-IF(ISNUMBER(_d2),_d2,TODAY()-(IF(_d2="Today","0",IF(_d2="Yesterday","1",LEFT(_d2,LEN(_d2)-LEN(" days"))))))
, lft, TEXTBEFORE(_d1,".",2)
, unq, UNIQUE(lft)
, sq, SEQUENCE(COUNTA(lft),,1,0)
, mm, --(TRANSPOSE(unq)=lft)
, wk, MMULT(--(TRANSPOSE(lft)=unq)*TRANSPOSE(lr>7),sq)
, mn, MMULT(--(TRANSPOSE(lft)=unq)*TRANSPOSE(lr>30),sq)
, stack, HSTACK(unq, wk, mn)
, VSTACK({"IP Subnet", "> Week", "> Month"}, stack))
This is what I was able to get working for me. It gives me the list of IP Subnets and the counts of how many of the IPs' "Last Response" was longer than 7 days or 30 days.
I have also used the Power Query example provided by Mayukh Bhattacharya. I was able to get this working as well. I did not test out the "let" formula that he provided as I already have a "let" formula working. I didn't chose that answer as the solution only because I was able to get the other "let" formula working first. I did have to tweak this answer as well in Power Query to look like this:
let
//AllData Uploaded in PQ Editor,
Source = Excel.CurrentWorkbook(){[Name="AllData"]}[Content],
//Date Type Changed
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Last Response", type text}}),
//Extracting the IP SUBNET
#"Extracted Text Before Delimiter" = Table.TransformColumns(#"Changed Type", {{"Address", each Text.BeforeDelimiter(_, ".", 1), type text}}),
//Replacing " days" in last response column
#"Replaced Value 1" = Table.ReplaceValue(#"Extracted Text Before Delimiter"," days","",Replacer.ReplaceText,{"Last Response"}),
//Replacing the "Today" and "Yesterday" with numbers
#"Replaced Value 2" = Table.ReplaceValue(#"Replaced Value 1", "Yesterday", "1", Replacer.ReplaceText, {"Last Response"}),
#"Replaced Value 3" = Table.ReplaceValue(#"Replaced Value 2", "Today", "0", Replacer.ReplaceText, {"Last Response"}),
//Removing " 12:00:00 AM" from Date Time since we changed the data type of lastresponse as text
#"Extracted Text Before Delimiter1" = Table.TransformColumns(#"Replaced Value 3", {{"Last Response", each Text.BeforeDelimiter(_, " 12:00:00 AM"), type text}}),
//Adding custom column return the numbers of days
#"Added Custom" = Table.AddColumn(#"Extracted Text Before Delimiter1", "Custom", each if Value.Is(Value.FromText([Last Response]), type number) then [Last Response] else Date.From(DateTime.LocalNow()) - Value.FromText([Last Response])),
//Changing the data type of the custom column to ensure they are numbers
#"Changed Type1" = Table.TransformColumnTypes(#"Added Custom",{{"Custom", Int64.Type}}),
//Removing unwanted columns
#"Removed Columns" = Table.RemoveColumns(#"Changed Type1",{"Last Response"}),
//Returning 1 for those days which are more than 7 else returning as 0
#"Added Conditional Column" = Table.AddColumn(#"Removed Columns", "> Week", each if [Custom] > 7 then 1 else 0),
//Returning 1 for those days which are more than 30 else returning as 0
#"Added Conditional Column1" = Table.AddColumn(#"Added Conditional Column", "> Month", each if [Custom] > 30 then 1 else 0),
//Grouping by each IP Address
#"Grouped Rows" = Table.Group(#"Added Conditional Column1", {"Address"}, {{"> Week", each List.Sum([#"> Week"]), type nullable number}, {"> Month", each List.Sum([#"> Month"]), type nullable number}}),
//Renamed the IP Address Column
#"Renamed Columns" = Table.RenameColumns(#"Grouped Rows",{{"Address", "IP Subnet"}})
in
#"Renamed Columns"
Now that I have started using Power Query I will probably continue with it as I have more transformations on this data to work on.
Using new 365 functions, generate unique IPs value, and count for >7 and >30 days.
If date retrieve differences, otherwise extract days number:
=LET(IP,TEXTBEFORE(AllIPAddresses,".",2),U,UNIQUE(IP),S,SEQUENCE(COUNTA(AllIPAddresses),,1,0),D,IFERROR(TODAY()-AllResponses,TEXTBEFORE(AllResponses," ")*1),W,MMULT((TRANSPOSE(IP)=U)*(TRANSPOSE(D)>7),S),M,MMULT((TRANSPOSE(IP)=U)*(TRANSPOSE(D)>30),S),HSTACK(U,W,M))
with HSTACK combine columns results.

date difference in one column based on second column value Power Query

I need to find the number of days between maximum and minimum date based on whenever there is a value in Tonnage.For example for the name K701 I need to find out number of days from 12/09/2022 till 30/09/2022 with the condition that tonnage is more than 0
In powerquery, filter tonnage, group on name, subtract the min from max date
let Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Filtered Rows" = Table.SelectRows(Source, each ([Tonage] <> 0)),
#"Grouped Rows" = Table.Group(#"Filtered Rows", {"Name"}, {{"days", each Number.From(List.Max(_[Shift.2]))-Number.From(List.Min(_[Shift.2]) ) }})
in #"Grouped Rows"

Calculate time for each person to stays in the factory

There are dates in the cell and times of entering and leaving the factory. I want to calculate how many hours each person has stay in the day they come to the factory. For this, I wrote a macro like this and I defined each person as sicil_no , but since there are multiple entries and exits at different times on the same date, I need to determine the last and first exit times for each day and subtract them. I didnt figure out how to do the last part
Sub macro()
Dim sicil_no As String
Dim i As Integer
Dim end_row As Long
Dim dates As Range
Dim gecis_yonu As String
Dim entry As String
Dim Exits As String
end_row = Cells(Rows.Count, 3).End(xlUp).Row
For i = 3 To end_row
sicil_no = Cells(i, 3).Value
dates = Cells(i, 1).Value
If Range("J", i).Value = "Exit" Then
Range("J", i).Value = exist
End If
If Range("J", i).Value = "Entry" Then
Range("J", i).Value = entry
End If
Next
For Each dates In Range("A", end_row)
Range("M", i).Value = exist - entry
Next
End Sub
One possible way is to use MAXIFS and MINIFS formula to get this result:
It can probably be done better, but if you select A:H and remove duplicates and uncheck column A then you get the result you are looking for I believe.
This assumes the date in column A is a true date and not just a text. If it's not a date then you will need to make it a date.
This can be done using DATEVALUE and RIGHT, LEFT, MID to make the string an accepted date format.
Then in E column you add this formula
=TEXT(A2,"YYYY-MM-DD")
In F:
=MAXIFS(A:A,E:E,TEXT(A2,"YYYY-MM-DD"),B:B,B2)
In G:
=MINIFS(A:A,E:E,TEXT(A2,"YYYY-MM-DD"),B:B,B2)
And lastly in H:
=F2-G2
When all formulas are on the sheet, select everything and copy, paste as values, then use remove duplicates like this:
and the result is this:
EDIT:
For completeness, this is how you convert your date to an accepted date format.
In M2 (example):
=MID(A2,7,4)&"-"&MID(A2,4,2)&"-"&LEFT(A2,2)&" "&RIGHT(A2,8)
then we need to use DATEVALUE and TIMEVALUE on this cell
N2:
=DATEVALUE(M2)+TIMEVALUE(M2)
You can obtain your desired output using Power Query, available in Windows Excel 2010+ and Office 365 Excel
You did not show what you want for output, but you can add to what I have shown which is the bare minimum Sicil, Date and Time between earliest and latest times. (Assuming each pair of times is entry/exit, you could also sum the differences between each pair of times per day)
In the Query, you can sort the results depending on whether you want to show by date or by employee.
Select some cell in your original table
Data => Get&Transform => From Table/Range
When the PQ UI opens, navigate to Home => Advanced Editor
Make note of the Table Name in Line 2 of the code.
Replace the existing code with the M-Code below
Change the table name in line 2 of the pasted code to your "real" table name
Examine any comments, and also the Applied Steps window, to better understand the algorithm and steps
M Code
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
//Add custom column with just the Date part for grouping
#"Added Custom" = Table.AddColumn(Source, "Date", each Date.From([Dates])),
//Group by Sicil No and Date
//Then extract the time in Factory as the last time less the first time
#"Grouped Rows" = Table.Group(#"Added Custom", {"Sicil No", "Date"}, {
{"Hrs in Factory", each List.Max([Dates]) - List.Min([Dates]), type duration}
}),
#"Changed Type" = Table.TransformColumnTypes(#"Grouped Rows",{{"Date", type date}})
in
#"Changed Type"
Edit
If you want to add up the actual time in the factory per day, taking into account the entry/exit times:
Assuming times are entered as pairs, where the first time is entry and the second is exit
Merely subtract one from the other to get each duration
The group as above and add the total durations per Sicil and Date
M Code
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
//Add custom column with just the Date part for grouping
#"Added Custom" = Table.AddColumn(Source, "Date", each Date.From([Dates])),
//Add Index column to access previous row
#"Added Index" = Table.AddIndexColumn(#"Added Custom", "Index", 0, 1, Int64.Type),
//if the Index number is an Odd number,
// then subtract the previous row from the current row to get the Duration
#"Added Custom1" = Table.AddColumn(#"Added Index", "Duration", each
if Number.Mod([Index],2)=0
then null
else [Dates]- Table.Column(#"Added Index","Dates"){[Index]-1}),
//Group by Sicil and Date
// SUM the durations
#"Grouped Rows" = Table.Group(#"Added Custom1", {"Sicil No", "Date"}, {
{"Time in Factory", each List.Sum([Duration]), type nullable duration}}),
#"Changed Type" = Table.TransformColumnTypes(#"Grouped Rows",{{"Sicil No", Int64.Type}, {"Date", type date}})
in
#"Changed Type"
further modification to account for "real" list not being sorted as needed, and also data errors with mismatch of entry/exitsAlso different routine to refer to previous row for speed improvements
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
//Change type especially datetime to Turkish culture (since I am in US)
#"Changed Type" = Table.TransformColumnTypes(Source,{
{"GECIS TARIHI", type datetime}, {"KART NUMARASI", type any}, {"SICIL NUMARASI", Int64.Type}, {"SOYADI", type text},
{"ADI", type text}, {"FİRMASI", type text}, {"GEÇİÇİ TAŞERON", type any}, {"BÖLÜM KODU", type any},
{"TERMINAL", type any}, {"GEÇİŞ YÖNÜ", type text}, {"GEÇİŞ DURUMU", type any}, {"ZONE", type any}}, "tr-TR"),
//Remove columns that will not appear in final report
#"Removed Columns" = Table.RemoveColumns(#"Changed Type",{"KART NUMARASI", "SOYADI", "ADI", "FİRMASI", "GEÇİÇİ TAŞERON",
"BÖLÜM KODU", "TERMINAL", "GEÇİŞ DURUMU", "ZONE"}),
//Sort for proper processing
#"Sorted Rows" = Table.Sort(#"Removed Columns",{{"SICIL NUMARASI", Order.Ascending}, {"GECIS TARIHI", Order.Ascending}}),
//add shifted columns to reference previous rows for entry/exit and time
//much faster than using the Index column method
ShiftedList = {null} & List.RemoveLastN(Table.Column(#"Sorted Rows", "GEÇİŞ YÖNÜ"),1),
Custom1 = Table.ToColumns(#"Sorted Rows") & {ShiftedList},
Custom2 = Table.FromColumns(Custom1, Table.ColumnNames(#"Sorted Rows") & {"GEÇİŞ YÖNÜ" & " Prev Row"}),
ShiftedList1 = {null} & List.RemoveLastN(Table.Column(Custom2, "GECIS TARIHI"),1),
Custom3 = Table.ToColumns(Custom2) & {ShiftedList1},
Custom4 = Table.FromColumns(Custom3, Table.ColumnNames(Custom2) & {"GECIS TARIHI" & " Prev Row"}),
//Calculate duration on the appropriate rows
#"Added Custom" = Table.AddColumn(Custom4, "Time in Factory", each
if [GEÇİŞ YÖNÜ] = "Exit" and [GEÇİŞ YÖNÜ Prev Row] = "Entry"
then [GECIS TARIHI] - [GECIS TARIHI Prev Row]
else null),
//Filter out the unneeded rows
#"Filtered Rows" = Table.SelectRows(#"Added Custom", each ([Time in Factory] <> null)),
//Remove the offset columns
#"Removed Columns1" = Table.RemoveColumns(#"Filtered Rows",{"GEÇİŞ YÖNÜ Prev Row", "GECIS TARIHI Prev Row"}),
//add Date column for grouping
#"Added Custom1" = Table.AddColumn(#"Removed Columns1", "Date", each DateTime.Date([GECIS TARIHI]),Date.Type),
//Group by Date and Sicil and SUM the Time in Factdory
#"Grouped Rows" = Table.Group(#"Added Custom1", {"SICIL NUMARASI", "Date"}, {
{"Time in Factory", each List.Sum([Time in Factory]), type duration}
})
in
#"Grouped Rows"

VBA change array data with with If statement

Mission: Calculate matching cable types and check to see how many reels I need depending on the length, qty and reel length.
Currently: My code will check the reel length on the appropriate line but it check it against all of the different types of cables.
How Can I: Change the array fill with only matching items?
I am checking to see if C = J and D = K and E = L. This is because left side of the sheet are individual lengths and the right are the total lengths.
rInpStk is the Reel length total.
'Fill array with cable lengths
For i = 0 To UBound(CutArr, 1)
Dim x As Integer
For x = 7 To lastrow 'Commenting out this If will get me the same result
If Cells(x, 3).Value = rInpStk.Offset(, -5) And _
Cells(x, 4).Value = rInpStk.Offset(, -4) And _
Cells(x, 5).Value = rInpStk.Offset(, -3) Then 'This does nothing
CutArr(i, 0) = rInputCuts.Cells(i + 1, 2) 'I want these to only populate the same cable types
CutArr(i, 1) = rInputCuts.Cells(i + 1, 1) 'If there is not a match then dont add that rows data to the array
Exit For
End If
Next x
Next i
Do I need to do an AutoFilter? If so how would I implement that.
After it's done I want it to continue to the next cable type.
Any help is much appreciated.
If your goal is to create the table you show under your TOTALS header, you can do this easily using Power Query which has been available since Excel 2010.
And if your data changes in your first table, a simple 'Refresh' will update the results table, and it will automatically adjust for changes in the amount of data, or types, in your first table.
Create a custom column of Total Length which is the product of your source data length*qty.
Then group by columns 3-7, with the SUM aggregate function.
Delete the unnecessary columns, and rearrange to get the desired column order.
This can all be done from the UI with the Custom Column formula of [LENGTH]*[QTY]
MCode
let
Source = Excel.CurrentWorkbook(){[Name="cableTbl"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"LENGTH", Int64.Type}, {"QTY", Int64.Type}, {"TYPE", type text}, {"SIZE", type text}, {"COL", type text}, {"CU ID", Int64.Type}, {"MAX ID", Int64.Type}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Custom", each [LENGTH]*[QTY]),
#"Removed Columns" = Table.RemoveColumns(#"Added Custom",{"LENGTH", "QTY"}),
#"Grouped Rows" = Table.Group(#"Removed Columns", {"TYPE", "SIZE", "COL", "CU ID", "MAX ID"}, {{"LENGTH", each List.Sum([Custom]), type number}}),
#"Reordered Columns" = Table.ReorderColumns(#"Grouped Rows",{"LENGTH", "TYPE", "SIZE", "COL", "CU ID", "MAX ID"})
in
#"Reordered Columns"
Results

How to replace a column name in Power Query by a variable to filter rows?

In a query developed with Excel Power Query I would like to replace the table column name with a variable, when I filter rows of a list. Unfortunately, I either get an error message (e.g. Expression Error: Column xx of table was not found) or no row is remaining after filtering even if it should.
In the example below the variable #"Filter" (= column name) is set to column "B" and used in the step #"Filter Rows" to filter the rows which contain a '1'. But the result is that no row is shown.
Any idea what's the reason and how to solve this? Maybe the variable needs to have a special data type?
Thanks in advance!
Table:
Table to be filtered
Code:
let
#"Filter" = "B",
Source = Excel.CurrentWorkbook(){[Name="Tabelle2"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"A", Int64.Type}, {"B", Int64.Type}}),
#"Changed Type1" = Table.TransformColumnTypes(#"Changed Type",{{#"Filter", type text}}),
#"Filtered Rows" = Table.SelectRows(#"Changed Type1", each Text.Contains(#"Filter", "1"))
in
#"Filtered Rows"
#"Filter" is the value "B", so the condition always returns false. The second parameter of Table.SelectRows takes a function which passes in the current row of the table as a record. You can do either of the following to use a variable to specify the column:
= Table.SelectRows(#"Changed Type", each Text.Contains(Record.Field(_, #"Filter"), "1"))
= Table.SelectRows(#"Changed Type", (x) => Text.Contains(Record.Field(x, #"Filter"), "1"))
each and _ are the same as (x) => and x in these cases. Record.Field(_, #"Filter") gets the value in the current row for the column #"Filter" refers to.

Resources