I am trying to take the Data in the scan it columns and conditionally filter it into the commercial or manufacturing sheet.
I tried writing a formula as an if function basically saying if it equals "Company" put it in manufacturing column, if not(if the rest) then put into commercial column.
I tried coding it backend in app script, but had an issue grabbing the last row from scan it and correctly adding the item #, vendor, and quantity into the last row of either Commercial or Manufactured.
The scan it section is an importrange function so more data will be entered into it once the code is working correctly.
I ran into dead ends with both. This is obviously an advanced code and I only did a little bit of coding in college. Below is a script that I had been messing with trying to get it to filter the data properly, but I couldn't get it to run. Any help would be appreciated!
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1')
//Get last rows for MFG
var mfgvalues = sheet.getRange(3, 5, sheet.getLastRow()).getValues();
//var mfglast = mfgvalues.filter(String).length;
//Get last rows for Comm
var commvalues = sheet.getRange(3, 1, sheet.getLastRow()).getValues();
//var commlast = commvalues.filter(String).length;
//Get last rows for Scann
var scanvalues = sheet.getRange(2, 12, sheet.getLastRow()).getValues();
//var scanlast = scanvalues.filter(String).length;
//Filter Accordingly
if (scanvalues == "IMMCO") {
var scanrange = sheet.getRange("L2:N").getLastRow().getValues();
//var scanlastrow = scanrange.getLastRow().getValues();
var mfgrow = sheet.getRange("E3:G").getLastRow();
scanlastrow.copyTo(mfgrow)
} else {
var scanrange = sheet.getRange("L:N").getLastRow.getValues();
//var scanlastrow = scanrange.getLastRow().getValues();
var commrow = sheets.getRange("A3:C").getLastrow()
scanlastrow.copyTo(commrow)
}
}
https://docs.google.com/spreadsheets/d/1D0FvVoTADi3t3ENPceB14QYYI4lNI6C3xj2OF-St7Is/edit?usp=sharing
GOOGLE SHEET OUTPUT WANTED
Option1:
Using FILTER() to filter your data set if vendor name is equal to "COMPANY" as mentioned in your description
Formula in Cell A3:
=filter(L3:N,LEN(L3:L)>0,UPPER(M3:M)<>"COMPANY")
Formula in Cell E3:
=filter(L3:N,LEN(L3:L)>0,UPPER(M3:M)="COMPANY")
Output:
Option2:
Using apps script to filter your data set.
Sample Code:
function filter(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1');
//Get item count for Scann
var scanCnt = sheet.getRange('L3:L').getValues().flat().filter(String).length;
Logger.log(scanCnt);
//Get last rows for Comm
var commLastRow = sheet.getRange('A1:A').getValues().flat().filter(String).length;
Logger.log(commLastRow);
//Get last rows for MFG
var mfgLastRow = sheet.getRange('E1:E').getValues().flat().filter(String).length;
Logger.log(mfgLastRow);
//Get Scann data if item count is not zero
if(scanCnt){
var commItem = [];
var mfgItem = [];
var dataRange = sheet.getRange(3,12,scanCnt,3);
var data = dataRange.getDisplayValues();
//Loop all scann data and separate mfg with comm
Logger.log(data.length)
data.forEach(item => {
Logger.log(item);
if(item[1].toUpperCase() == "COMPANY"){
mfgItem.push(item);
}else{
commItem.push(item);
}
});
Logger.log(mfgItem);
Logger.log(commItem);
//Append comm items
sheet.getRange(commLastRow+1,1,commItem.length,commItem[0].length).setValues(commItem);
//Append mfg items
sheet.getRange(mfgLastRow+1,5,mfgItem.length,mfgItem[0].length).setValues(mfgItem);
//Optional: Clear content of scann column
dataRange.clearContent();
}
}
What it does?
Get the item count to filter in Scan it column by selecting the range L3:L. Get its value. Change 2-d array to 1-d array using array.flat(). Use array.filter() to remove empty values. Then get its length
Get the last row of Commercial(ColumnA) and Manufactured(ColumnE) column.
If item count obtained in step1 is not zero. Then get the data range and its value
Loop all data value (by row) one-by-one. Check if vendor index is equal to "COMPANY" then add it to mfgItem array. Else, add it to commItem array
Append mfgItem and commItem under Manufactured Column and Commercial Column
(Optional) Clear the data under Scan-it Column
Note:
You can check the execution log to further understand the procedure done. I included some debug logs in the sample code.
Output:
Related
My users can enter new products on a separate sheet for review from the buyer. If accepted, the buyer then runs the script from the menu.
The process works perfectly, copying the new information into the price book and then clearing the data from the New Item sheet. But, the process seems to always add two blank cells, even though there are no extra rows in either sheet.
function addNewItems() {
//Get new item data from New Items Sheet
var ss = SpreadsheetApp.getActive();
var s = ss.getSheetByName("New Items");
s.activate();
//define non-contiguous data ranges from source sheet fpr clearing after copying
var newInput1 = ss.getRange("New Items!A2:K");
var newInput2 = ss.getRange("New Items!N2:O");
var newInput3 = ss.getRange("New Items!Q2:R");
// Get last row of data from source sheet
lastR = s.getLastRow();
// Select range of data with new item information (17 is the last column of data)
var newItems = s.getRange(2,1,lastR,17).getValues();
//Switch to target sheet to add new records into Price Book
var ts = ss.getSheetByName("Price Book");
ts.activate();
//Find last row of Price Book data and add one to get next row
tsIns = ts.getLastRow();
//Start at the next row and insert the data range from the New Item sheet
var newInsert = ts.getRange(tsIns +1,1,lastR,17).setValues(newItems);
//Clear data from new item sheets after copying data to the Price Book
newInput1.clearContent();
newInput2.clearContent();
newInput3.clearContent();
}
Try this:
function addNewItems() {
var ss = SpreadsheetApp.getActive();
var sh = ss.getSheetByName("New Items");
let lastR = sh.getLastRow();
var newInput1 = sh.getRange("A2:K" + lastR);
var newInput2 = sh.getRange("N2:O" + lastR);
var newInput3 = sh.getRange("Q2:R" + lastR);
var newItems = sh.getRange(2, 1, lastR - 1, 17).getValues();
var tsh = ss.getSheetByName("Price Book");
tsIns = tsh.getLastRow();
tsh.getRange(tsIns + 1, 1, lastR - 1, 17).setValues(newItems);
newInput1.clearContent();
newInput2.clearContent();
newInput3.clearContent();
}
I don't know about 2, but definitely 1. In getRange, the third parameter is number of rows to get or set. Since you getValues() starting at row 2 you should subtract 1 from lastR since its value is the total number of rows with values including the headers.
Therefore you should change the following 2 lines of code as shown.
var newItems = s.getRange(2,1,lastR-1,17).getValues();
var newInsert = ts.getRange(tsIns +1,1,lastR-1,17).setValues(newItems);
Ok, title might be confusing. I mean, I'm confused just trying to make this work.
I essentially have 3 sheets.
The Search Sheet - Has a search box & macro button.
The Data Sheet - self explanatory.
The Target Sheet - Sorted into columns.
So, what I'm needing to happen is: when a user enters a value in the Search Sheet & hits the "go" button, it searches the Data sheet for any cells in column B that match. On a match, it modifies the matched cell so it won't match on another search, then copies the adjacent cell 'A' value into the first column of the Target Sheet, contuingin down the sheet & adding each match to the same column.
On a new search, the results will show in the 2nd column, etc...
Search1 = "L1" | Search 2 = "L3"
Data Sheet:
DataSheet
Result Sheet:
Result Sheet
Here's my shitty attempt at scripting it. I probably defined the wrong things & didn't define right things. I'm trying to wrap my head around it, but I think I've gotten into the deep end too fast.
function moveTest() {
var ss = SpreadsheetApp.getActiveSpreadsheet(); //Spreadsheet
var source = ss.getSheetByName("Close"); //Input Sheet
var sourceData = ss.getSheetByName("Raw_Data"); //Data Sheet (List of all data)
var target = ss.getSheetByName("Pallet_Data"); //Target Sheet
var dataRange = data.getRange("B:B").getValues; //Range To Search on Data Sheet
var lastcolumn = target.getLastColumn(); //Last Column of Target
var searchval = [[source.getRange("A2").getValue()]]; //Search String
var targetRange = target.getRange("A"+(lastcolumn+1)+":C"+(lastcolumn+1)); //Define New Range n+1
//var rIndex = getRowIndex(); //row index of Data
//var cIndex = getColumnindex(); //column index of Data
while (dataRange has_data) { // For each row that has data in column B...
if (Bn = searchval) { // If B in row 'n' matches the search value
var rIndex = sourceData.getRowIndex(); // Define that row
var match = sourceData.getActiveCell // Defines B of matched row
var firstcell = rIndex.getRange(??) // Define cell A of that row
match.setValue('Moved'); // Change value of B in matched row so it won't match on new search
firstcell.copyTo(lastcolumn) //Copy Cell A of defined row into last column of target sheet
//Add next match to bottom of SAME Column then start NEW Column when function is run again.
}
}
Thanks
Solution:
Your script could look like this:
function cellMatch() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = ss.getSheetByName("Data");
var sheet2 = ss.getSheetByName("Result");
var sheet3 = ss.getSheetByName("Search");
var lr = sheet1.getLastRow();
var data = sheet1.getRange(2,1,lr-1,2).getValues();
var lc = sheet2.getLastColumn()+1;
var key = sheet3.getRange("B1").getValue();
var matched = [["Search "+lc]];
for (var i=0; i<lr-1; i++) {
if (data[i][1] == key) {
var temp = [];
temp.push(data[i][0]);
matched.push(temp);
}
}
var result = sheet2.getRange(1,lc,matched.length);
result.setValues(matched);
}
This should take the search key from Search sheet, compare it with the Data sheet, and place the results into Result sheet.
Sample Data:
This is the result after executing the script twice, for L1 and L3.
I have a sheet that I need to get values from and set in a new sheet, one of these values requires me to slice string value at indices 20,26. I can achieve this using .getValue().slice(20,26) and .setValue(). However, the same data is set in all rows, which is to be expected since I am only getting a single cell of data. To resolve this I tried a for loop which failed.
When I attempt .getValues().slice(20,26) it returns an empty array which throws the following error: The number of rows in the data does not match the number of rows in the range. The data has 0 but the range has 20.
My code is below and I welcome any guidance.
function pj() {
// Get Active spreadsheet.
var sheet = SpreadsheetApp.getActiveSpreadsheet();
//Get last row processed and update
var startRow =sheet.getSheetByName("Index").getRange("A1").getValue();
startRow++;
// Get payments sheet.
var paymentSheet = sheet.getSheetByName("Payments");
var clientSheet = sheet.getSheetByName("Client Details");
var lastRow = paymentSheet.getLastRow();
//Inputs
var firstName = paymentSheet.getRange(startRow, 3, (lastRow-startRow+1), 1).getValues();
var lastName= paymentSheet.getRange(startRow, 4, (lastRow-startRow+1), 1).getValues();
var paymentId = paymentSheet.getRange(startRow, 14, (lastRow-startRow+1), 1).getValues().slice(20,26);
}
//Outputs
clientSheet.getRange(2,1,(lastRow-startRow+1),1).setValues(firstName);
clientSheet.getRange(2,8, (lastRow-startRow+1),1).setValues(paymentId);
//Update the last row processed
sheet.getSheetByName('Index').getRange("A1").setValue(lastRow);
}
Please see image of the sheet I am working with, as you will see column N contains a payment ID, which holds a unique identifier for the client that I need to extract in order to upload this data into Salesforce. It seems the issue is that Logger.log is reporting the string correctly as it goes through the array, but is reporting the length as 1. I've tried changing the format of that column various ways, Text, Number etc but it doesn't seem to make any difference to the reported length. I'm assuming this is why the split function isn't working, but I'm not sure why it's happening?Sheet
I guessed at a lot of this but it should look similar to this:
function pj() {
var ss=SpreadsheetApp.getActive();
var isht=ss.getSheetByName("Index");
var startRow=isht.getRange("A1").getValue()+1;
var psht=ss.getSheetByName("Payments");
var csht=ss.getSheetByName("Client Details");
var lastRow=psht.getLastRow();
var prg=psht.getRange(startRow,1,psht.getLastRow()-startRow+1,14);
var pvals=prg.getValues();
pvals.forEach(function(r,i){
csht.getRange(i+2,1).setValue(r[2]);
csht.getRange(i+2,2).setValue(r[3]);
csht.getRange(i+2,8).setValue(r[13].slice(20,26));
});
isht.getRange("A1").setValue(csht.getLastRow());
}
I'm trying to use Google Apps Script to communicate with Google Sheets to do the following:
We're trying to convert data from one Point of Sale system to a new one. In order to do this, I need to take certain columns of a sheet, manipulate them in various ways, and repopulate another sheet with the resulting data. I need to find products without a SKU number, and assign them a new one, starting at 10110 and incrementing from there.
function sku() {
// "From" Spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("New POS Data");
// "To" Spreadsheet
// Spreadsheet key: the string at the end of the URL
var ssraw = SpreadsheetApp.openById("1BH-j4cOW9Ntg6FlPNXmNCUId_pm9BgyAh0cwrwB4z_A");
var sheetraw = ssraw.getSheetByName("Old POS Data");
var max = sheet.getLastRow();
// SKU / UPC
var range = sheetraw.getRange(2,18,max);
var data = range.getValues();
// Assign new sku if no old one
var skunum=[10110];
var newData = new Array();
for (var y = 0; y <= max; y++) {
if (data[y]==""){
newData.push(skunum);
skunum++;
var skunum=[skunum];
}
else {newData.push(data[y]);}
}
sheet.getRange(2,3,max).setValues(newData);
}
This gives me the error "Incorrect range height, was 1 but should be 30 (line 26, file "SKU")"
If I remove the brackets around newData in the last line, I get "Cannot convert Array to Object[][]. (line 27, file "")"
This has been driving me mental, if anyone can offer help, I would be very grateful.
Even if you get a one row or one column vector with getData() you will get an Object[][].
when you do:
if (data[y]==""){
newData.push(skunum);
skunum++;
var skunum=[skunum];
}
You check if [cellFromColumn] == "" which will evaluate to false as it's an array.
You then push the new/old sku number to a simple array which, for spreadsheets, is one row of columns.
Instead you want to push into the array a one element array containin the sku number like this:
newData.push(skunum);
...
newData.push([data[y]]);
This will create an array of rows, each row is an array with one element (one column)
Let's say I have a lot of columns and one of them contains "impressions" string (on row 3). What I need to do is to:
1) Find the cell with "impressions" string
2) Get column number or i.e. "D"
3) Based on what I got paste a formula into i.e. D2 cell which gets AVERAGE from a range D4:D*last*
I couldn't find it anywhere so I have to ask here without any "sample" code, since I have no idea on how to achieve what I want. (3rd one is easy but I need to get that "D" first)
There's no way to search in Google Apps Script. Below is a function that will accomplish the first 2 parts for you (by iterating over every cell in row 3 and looking for "impressions"):
function findColumnNumber() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Sheet1'); // insert name of sheet here
var range = sheet.getDataRange(); // get the range representing the whole sheet
var width = range.getWidth();
// search every cell in row 3 from A3 to the last column
for (var i = 1; i <= width; i++) {
var data = range.getCell(3,i)
if (data == "impressions") {
return(i); // return the column number if we find it
}
}
return(-1); // return -1 if it doesn't exist
}
Hopefully this will allow you to accomplish what you need to do!
The indexOf method allows one to search for strings:
function findColumnNumber() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet() //whatever tab the code is run on
var data = sheet.getDataRange().getValues();
var header_row_num = 1; // TODO: change this to whichever row has the headers.
var header = data[header_row_num -1] //Remember JavaScript, like most programming languages starts counting (is indexed) at 0. For the value of header_row_num to work with a zero-index counting language like JavaScript, you need to subtract 1
//define the string you want to search for
var searchString = "impressions";
//find that string in the header and add 1 (since indexes start at zero)
var colNum = header.indexOf(searchString) + 1;
return(colNum);