Q1: I have written a VB script that works, but would like it to be more dynamic.
My Script is as follows
Sub UpdateMaster()
Dim ws As Worksheet
Dim tracker As Worksheet
Dim r As Range
Application.ScreenUpdating = False
If MsgBox("Would you like to update the tracker?", vbYesNoCancel) = vbYes Then
Set ws = ThisWorkbook.Sheets("Bulk") 'data set where users input the info
Set tracker = ThisWorkbook.Sheets("TRACKER") 'master data set where all user data entries become added
Set r = ws.Range("A1").CurrentRegion.Offset(1) ' removes headers
r.Copy Destination:=tracker.Range("A" & Rows.Count).End(xlUp).Offset(1, 0)
'pastes to first available row in tracker sheet
MsgBox "Tracker Updated"
Else
MsgBox "Process Cancelled"
End If
Application.ScreenUpdating = True
End Sub
I have pre-set formulas in columns A/D/E/F/G/J (refer to as extracted info), and also a reset macro where the manual data points inputted in columns B/C/H (refer to as manual) become cleared. Say rows 1 - 10 have data that is entered in the manual columns, the data then shows up in the extracted info columns likewise. But because I've filled the formulas to row 1000, if I use my VB script UpdateMaster, it will copy everything until row 1000 and paste to the tracker worksheet - essentially the excess blank cells with formulas in them.
If I want it to copy the contents up until the last data point entered in column C, but still include the data in column A, which part of the code do I revise?
Example: Column C Row 10 has last input of data, copy all contents up until row 10. (Even though there is formulas in cells up until row 1000)
Q2: Can blank cells be ignored in formulas for a specific case? On a separate worksheet, I have a list of all data - and this is the information that is pulled with the formulas on the data logging sheet. These formulas (basic index/match) are contingent on data in column C. =IFERROR(INDEX(Sheet1!G:G,MATCH(CONCATENATE(C2),Sheet1!A:A,0)),"Not Found").
On the worksheet "sheet1" that has all the data, there are some cells in column A that are blank where the formula is trying to match that info - while there is still data within that row except for A, and the formula finds a match.
So, I'd like to ignore those small cases, because the formulas are showing a solution or finding a match when in reality I just have those cells blank for when I want to put info later. It reads the blank cell as data that matches my index/match. Again, the formulas are just down until 1000, so if i only input actual data up until row 10, the data in the latter will show a match even though i didn't input any data and its blank.
Q1
replace:
Set r = ws.Range("A1").CurrentRegion.Offset(1) ' removes headers
with:
c_l = ws.Cells(ws.Rows.Count, "C").End(xlUp).Row
Set r = ws.Range("A2:J" & c_l)
(remove all Dim statements or include Dim c_l as long
as you prefer).
Q2
pre-requisite: 365 compatible excel.
=LET( x_, TEXTJOIN("", 1,C2),IF(x_="", "",IFERROR(INDEX(A:A,MATCH(x_,TEXT(G:G,"0"),0)),"n/a")))
notes:
if you don't want to return a blank from col A (even if C2 matches a non-blank in col G) then something like this would do trick:
=LET( x_, TEXTJOIN("", 1,C2),y_,IF(x_="", "",IFERROR(INDEX(A:A,MATCH(x_,TEXT(G:G,"0"),0)),"n/a")),if(y_="","n/a",y_))
concatenate,textjoin etc. convert numerical values to text, so surprised if any lookup worked using your fn if col G
contained numerical due to your concatenate fn on lookup reference C2
.
Spanning entire cols for index/match (especially with additional fns like text
per above) is compute-intensive...
...more effective fn would be limiting the range (dynamically or otherwise), e.g.
=LET(a0_,OFFSET(A1,,,10000,COLUMNS(A1:G1)),a1_,BYCOL(a0_,LAMBDA(a_,MAX(FILTER(SEQUENCE(ROWS(a0_)),IFERROR(--(a_<>""),0))))),a2_,MAX(a1_), x_, TEXTJOIN("", 1,C2:E2),y_,IF(x_="", "",IFERROR(INDEX(OFFSET(A2,,,a2_),MATCH(x_,TEXT(OFFSET(G2,,,a2_),"0"),0)),"n/a")),y_)
Modify the lookup key (i.e. C2:E2
within textjoin
as req.)
This version doesn't care if you return a blank from col A (so long as you're matching on col G - modify in line with 1st bullet as req. customization)..
Use a static range that has sufficient rows (e.g. 1000-2000) if you know that you're unlikely to have cells populated beyond that in whatever sheet you're looking up from... this simplifies above substantively (i.e. trash the bycol
, max(a1_)
, and reference the relevant range directly within Index
instead of using this fancy offset
variant)...
Another alternative, assuming you only contain numerical values in lookup ref (i.e. result of the concatenate/textjoin) and lookup range (col G
) is simply to use --textjoin("",1,C2:E2)
- or 'whatever' range you wish to join. This converts it back to numerical (assuming it can be, else you'll obviously get an error..)
FYI - I prefer textjoin
(vs. concatenate
) for couple reasons: you can either exclude or include blank cells in C2:E2
(/whatever) depending upon 2nd arg {currently set to 1, i.e. exclude}.. My main gripe,however, with concat..
is that you cannot reference a range of cells to join (have to input C2,D2,E2
vs C2:E2
- from recollection at least...
̿̿ ̿̿ ̿’̿’\̵͇̿̿\З= ( ▀ ͜͞ʖ▀) =Ε/̵͇̿̿/’̿’̿ ̿ ̿̿ ̿̿ ̿̿