Perform Vlookup from sheet 1 to sheet 2 and pass a matching value found in sheet 2 to external API - api

I have Sheet 1 which contains a bunch of data including names of users. Sheet 2 contains users' names with their ID. I want to do some kind of mapping and I am not sure how to go about it.
Ideally, I would like to read a range of rows, say AA: AE and match the names in sheet 1 with the ones in sheet 2 with ID, and then POST the ID in sheet 2 to an external API.
Here is the code:
function getData(startRow, endRow) {
var ss = SpreadsheetApp.getActive();
//Temporary calc sheet
var calcSheet = ss.getSheetByName("CALC_SHEET");
//Clear data range from previous calculations
calcSheet.getDataRange().clear();
//Clear data range from previous calculations
calcSheet.getDataRange().clear();
//formula template
var formulaTemplate = '{ArrayFormula(IFERROR(VLOOKUP(Form Responses 1!AF1{{startRow}}:AL{{endRow}},{UserID mapping!B1:B132,user_ids!C1:C132},2,false),"")),QUERY(UserID mapping!A{{startRow}}:C{{endRow}}, "select *")}';
//insert startRow and endRow into the formula
var formula = formulaTemplate.split("{{startRow}}").join(startRow).split("{{endRow}}").join(endRow);
//insert formula into the helper sheet
calcSheet.getRange(1, 1).setFormula(formula);
//write changes to the spreadsheet
SpreadsheetApp.flush();
var values = calcSheet.getDataRange().getValues();
//overwrite formula with values
calcSheet.getDataRange().setValues(values);
return values;
}

Here's a quick example to get you up and running. Below is my sheet with mock user data (not sorted):
The 2nd sheet contains user names mapped to their respective ids:
Step 1
The task is basically to match unique user id from the 'user_ids' sheet to each row in 'user_data' table.
=ArrayFormula(IFERROR(VLOOKUP(user_data!A1:A10,{user_ids!B1:B10,user_ids!A1:A10},2,false),""))
Note that because VLOOKUP uses the first column as the index column, I had to reverse the order of columns in the user_ids sheet so that column B (name column) comes first. This function returns user ids for every single row in 'user_data' (in correct order).
The last step is to display other columns from user data. Final formula
={ArrayFormula(IFERROR(VLOOKUP(user_data!A1:A10,{user_ids!B1:B10,user_ids!A1:A10},2,false),"")),QUERY(user_data!A1:C10, "select *")}
Result:
What if you want to do the same thing programmatically? You can use the same formulas! The downside is that you may need to create a temporary sheet for calculations - think of it as your cache or database. Of course, you can hide the helper sheet or delete it when it's not in use.
Below is the function that utilizes the above approach to return specified rows matched with their ids. Of course, you can still make it better by passing column indexes and handling errors
function getData(startRow, endRow) {
var ss = SpreadsheetApp.getActive();
//Temporary calc sheet
var calcSheet = ss.getSheetByName("calc_sheet");
//Clear data range from previous calculations
calcSheet.getDataRange().clear();
//formula template
var formulaTemplate = '{ArrayFormula(IFERROR(VLOOKUP(user_data!A{{startRow}}:A{{endRow}},{user_ids!B1:B10,user_ids!A1:A10},2,false),"")),QUERY(user_data!A{{startRow}}:C{{endRow}}, "select *")}';
//insert startRow and endRow into the formula
var formula = formulaTemplate.split("{{startRow}}").join(startRow).split("{{endRow}}").join(endRow);
//insert formula into the helper sheet
calcSheet.getRange(1, 1).setFormula(formula);
//write changes to the spreadsheet
SpreadsheetApp.flush();
var values = calcSheet.getDataRange().getValues();
//overwrite formula with values
calcSheet.getDataRange().setValues(values);
return values;
}

Related

how to insert a row in the middle of the table. google sheets API

I can't figure out how to add a row to a certain place always adds to the end of the table.
{
SpreadsheetsResource.ValuesResource.AppendRequest.ValueInputOptionEnum valueInputOption = SpreadsheetsResource.ValuesResource.AppendRequest.ValueInputOptionEnum.RAW;
SpreadsheetsResource.ValuesResource.AppendRequest.InsertDataOptionEnum insertDataOption = SpreadsheetsResource.ValuesResource.AppendRequest.InsertDataOptionEnum.INSERTROWS;
ValueRange requestBody = new ValueRange();
requestBody.Range = range + "!A4:A";
IList<Object> obj = new List<Object>();
obj.Add("A2");
obj.Add("B2");
IList<IList<Object>> values = new List<IList<Object>>();
values.Add(obj);
requestBody.Values = values;
SpreadsheetsResource.ValuesResource.AppendRequest request = service.Spreadsheets.Values.Append(requestBody, spreadsheetId, range+"!A4:A");
request.ValueInputOption = valueInputOption;
request.InsertDataOption = insertDataOption;
AppendValuesResponse response = request.Execute();
}```
As you can see in the official documentation, values appended via spreadsheets.values.append are appended "after the last row of the table". With append, you cannot decide where exactly you want to add your data. The API looks for a "table" based on the input range you specify, as explained here.
If you want to add a row in the exact place you want, you should first (1) insert an empty range and then (2) write your desired values to the empty range. You would have to do two successive requests:
In order to insert the empty range where you want to append your data to, use the method spreadsheets.batchUpdate and in the field requests, provide an insertRange request. Specify the row and column indexes you want to insert your range to (field range) and whether the previously existing cells should be shifted down or right (field shiftDimension).
Second, once you have empty cells where you want your values to be, you can use spreadsheets.values.batchUpdate to write those values (defined in the field data). Check this guide to writing values for a detailed explanation.
Reference:
Appending values
Method: spreadsheets.batchUpdate
InsertRangeRequest
Method: spreadsheets.values.batchUpdate
Writing

how to combine cell vertically in excel

It might be the most silly question in planet. how can I merge two cell values vertically in a repeated manner. as like this:
Column A and B has 400+ cells therefore it is impossible to do what I want to achieve manually.
Note: I want to merge B into A.
You can create a simple loop in VBA that runs through each cell in the data range then adds it to the output column
Sub Merge()
Dim data As Range
Dim cell As Range
Dim output As Range
Dim i As Integer
Set data = Range("A2:B4")
Set output = Range("D2")
i = 0
For Each cell In data
output.Offset(i, 0) = cell
i = i + 1
Next
End Sub
You can use the INDEX function to refer to each cell. If data is in A2:B4, this formula works in any column but must start in row 2 and can then be filled down:
=INDEX($A$2:$B$4,ROW()/2,MOD(ROW(),2)+1)
The formula uses the current row as a counter. On every even row it gets a value from the first column of data and on every odd row it gets a value from the second column of data. After every 2 rows it gets values from the next row of data.

Excel Autofilter, Copy selection, Paste to new sheet

I have a table with source data in columns Regions!A6:R553.
In Regions!A3:R3, I have formulas that pull specific information out of my data table in Regions!A6:R553 that I want copied to a different sheet.
Column A acts as my project name column, while column B holds ID numbers. In my case, there are multiple ID numbers per project.
I am looking for a script to filter and loop through all the unique order numbers in Column B one by one, then copy cells A3:R3 to RegionsSummary!A12:R12 for as many rows as there are unique order numbers (i.e, add rows to the table).
Here is a screengrab of my data sheet, "Regions":
i.stack.imgur.com/aTPuw.png
Here is a screengrab of the empty template sheet "RegionsSummary":
i.stack.imgur.com/9Ukz5.png
Example: Assume there are 5 projects in my data sheet. I will filter the data using another macro to select Project_1. I would then like a command button to active a macro that will filter to the first order number in Column B, copy Regions!A3:R3 to RegionsSummary!A12:R12, then filter to the second order number in Project_1, and repeat the process. This should go on until all unique ID numbers have been filtered and looped through.
Here is a screengrab of what a final product should look like:
i.stack.imgur.com/9Ukz5.png
Here is a link to the file: Final Output Example
I would go with an easier solution than a Macro with certain constraints. I am not able to access your sheet, so I will make a sample excel.
STEPS:
Create a list of unique projects for a dropdown (COPY Regions!A5:A10000 to a new sheet > Data > Remove Duplicates) . Create the dropdown (Data Validation > List > Select Range) using Data Validation in "Example_Result" sheet- C7.
In "Regions", in Col S, put the below formula
=S6&"_"&COUNTIF($S$6:S6,S6)
Copy this formula down for the entire sheet or as long as you expect the sheet to grow
In "Example_Result", insert an index column (1 to 1000, in Col A if you expect each project to have 1000 or less order numbers) from A12 onwards.
Along the columns (B onwards) of Row 11 include the names of the variables from Regions (Assessment Project, Highway etc).
Insert the below formula in B12 to S1000 (depending on number of variables) of Example_Result:
=IFERROR(INDEX(Regions!$A$5:$S$10000,MATCH($C$7&"_"&A$12,Regions!$S$5:$S$10000,0),MATCH(B$11,Regions!$A$5:$H$5,0)),"")

VLOOKUP with button click

I'm trying to write some code for a button click to perform a VLOOKUP.
Sheet1 = Payment Form, Sheet2 = Global, Sheet3 = Details
Button will be on Sheet "Payment Form".
This would be the code for Cells in Global Sheet,
O1 = =VLOOKUP(BA,Details!A:H,8,0)
P1 = =VLOOKUP(BA,Details!A:H,6,0)
Q1 =VLOOKUP(BA,Details!A:H,5,0)
I need this to loop through all rows as the amount can change each month, if a match is found the perform the VlookUp, is no match is found, the delete the row from the Details Sheet.
For Example: Global, Cell B1 = 27801. In Details match found, then do the above codes from Columns O, P & Q.
Global, B2 = 27802. In Details no matching record found, row deleted. Continue to row 3 & 4 ......
what I suggest is you put all the value in table will be more efficient (not simply enter in the excel cell), you need create the table by INSERT ->Table. It will look like this :
Do this also for the Details :
Back to global worksheet, just need enter 1 row of formula, the rest of the rows in the same column will have the same formula "style"
Column O :=VLOOKUP([Column BA],Table2[[#All],[Column1]:[Column8]],8,FALSE)
Column P :=VLOOKUP([Column BA],Details!A:H,6,FALSE)
Column Q :=VLOOKUP([Column BA],Details!A:H,5,FALSE)
To remove the unwanted row, just filter out the blanks value in that columns will do.

Copying Row Info from one sheet to another based on match

I have an excel book that has two sheets: 1) Import 2) Pricing Rules.
Pricing Rules Sheet
The A column is what I need to match on. Example values include STA_PNP4, STA_PST.. and others. There are potentially around 50 different rows in the sheet, and it will continue to grow over time. Then for each row, there are pricing values in columns B to CF.
Import Sheet
This sheet has the same number of columns, but only Column A is filled out. Example values include STA_PNP4_001_00, STA_PNP4_007_00, STA_PST_010_00.. and many more.
What I need to do:
If the text in Import Sheet Column A before the second "_" matches the column identifer in Pricing Rules Sheet Column A, copy the rest of B to CF of Pricing Rules sheet for that row into the Import sheet for the row it matched on.
Any idea on where to begin with this one?
Why don't you do it using formulas only?
Assuming :
1.) Data in Import Sheet is
(col A)
STA_PNP4_007_00
STA_PNP4_001_00
STA_PNP4_001_00
.
.
2.) Data in Pricing Rules Sheet
(Col A) (col B) (ColC) (Col D) .......
STA_PNP4 1 2 3 .....
STA_PST 4 5 6 .....
STA_ASA2 7 8 9 .....
Then write this formula in B1 cell of Import Sheet
=IFERROR(VLOOKUP(LEFT(A1,FIND("",A1,FIND("",A1)+1)-1),PricingRules!$A$1:$CF$100,2,0),"")
Drag it down in column B
and For Column C , D just change index num from 2 to (3 for C) , (4 for D) and like that.
Because it will continue to grow over time you may be best using VBA. However, even with code I would start by applying the ‘groups’ via formula, so as not to have a spreadsheet overburdened with formulae and hence potentially slow and easy to corrupt. Something like part of #xtremeExcel’s solution which I repeat because the underscores have been treated as formatting commands in that answer:
=LEFT(A1,FIND("_",A1,1+FIND("_",A1))-1)
I’d envisage this (copied down) as an additional column in your Import Sheet - to serve as a key field to link to your Pricing Rules Sheet. Say on the extreme left so available for use by VLOOKUP across the entire sheet.
With that as a key field then either:
Write the code to populate Pricing Rules Sheet as frequently as run/desired. Either populating ‘from scratch’ each time (perhaps best for low volumes) or incrementally (likely advisable for high volumes).
Use VLOOKUP (as suggested). However with at least 84 columns and, presumably, many more than 50 rows that is a lot of formulae, though may be viable as a temporary ‘once off’ solution (ie after population Copy/Paste Special/Values).
A compromise. As 2. But preserve a row or a cell with the appropriate formulae/a and copy that to populate the other columns for your additions to your ColumnA and/or ColumnA:B.
Thanks for the input guys.
I got it implemented via a method like this:
{=VLOOKUP(LEFT($A4,7),PricingRules!A3:CF112,{2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84},FALSE)}
That is my ugly function, applied across a whole row, to look up and copy from my pricing rules every column when it finds a match.
Below is the function that I have created for above scenario. Its working as per the requirement that you have mentioned.
Sub CopyData()
Dim wb As Workbook
Dim importws As Worksheet
Dim PricingRulesws As Worksheet
Dim Pricingrowcount As Integer
Dim importRowCount As Integer
Dim FindValue As String
Dim textvalue As String
Dim columncount As Integer
Dim stringarray() As String
'Enter full address of your file ex: "C:\newfolder\datafile.xlsx"
Set wb = Workbooks.Open("C:\newfolder\datafile.xlsx")
'Enter the name of your "import" sheet
Set importws = Sheets("Import")
'Enter the name of your "Pricing" sheet
Set PricingRulesws = Sheets("PricingRules")
For Pricingrowcount = 1 To PricingRulesws.UsedRange.Rows.Count
FindValue = PricingRulesws.Cells(Pricingrowcount, 1)
For importRowCount = 1 To importws.UsedRange.Rows.Count
textvalue = importws.Cells(importRowCount, 1)
stringarray = Split(textvalue, "_")
textvalue = stringarray(0) & "_" & stringarray(1)
If FindValue = textvalue Then
For columncount = 2 To PricingRulesws.UsedRange.Columns.Count
importws.Cells(importRowCount, columncount) = PricingRulesws.Cells(Pricingrowcount, columncount)
Next columncount
End If
Next importRowCount
Next Pricingrowcount
End Sub