how do I change this google app script to hide sheets columns instead of rows based on column dates - sql

so I'm a long way form a competent programmer, but I do dabble in google sheets scripts.
I previously had a script running on a timer trigger to hide rows based on dates found in column A.
function min() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("OLD");
var v = s.getRange("A:A").getValues();
var today = new Date().getTime() - 86400000‬
for (var i = s.getLastRow(); i > 1; i--) {
var t = v[i - 1];
if (t != "") {
var u = new Date(t);
if (u < today) {
s.hideRows(i);
}
}
}
}
function max() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("OLD");
var v = s.getRange("A:A").getValues();
var today = new Date().getTime() + 86400000
for (var i = s.getLastRow(); i > 1; i--) {
var t = v[i - 1];
if (t != "") {
var u = new Date(t);
if (u > today) {
s.hideRows(i);
}
}
}
}
function SHOWROWS() {
// set up spreadsheet and sheet
var ss = SpreadsheetApp.getActiveSpreadsheet(), sheets = ss.getSheets();
for(var i = 0, iLen = sheets.length; i < iLen; i++) {
// get sheet
var sh = sheets[i];
// unhide rows
var rRows = sh.getRange("A:A");
sh.unhideRow(rRows);
}
}
this would be set to run at midnight every night so as to hide all rows not +-1 day from the current date.
I have now switched to using this document primarily through the android app I need to swap the input layout Moving dates from rows and values in columns to the inverse, values are now in rows and the dates are in columns, inputing vertical values would be much quicker....but honestly its more about understanding what im doing wrong thats really motivating my search for a answer.
can anyone help me modify my old script to work on this changed sheet.
my attempts fall flat..eg:
function min() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("OLD");
var v = s.getRange("1:1").getValues();
var today = new Date().getTime() - 86400000‬
for (var i = s.getLastColumn(); i > 1; i--) {
var t = v[i - 1];
if (t != "") {
var u = new Date(t);
if (u < today) {
s.hidecolumns(i);
}
}
}
}
example spreadsheet:
https://docs.google.com/spreadsheets/d/1EjRIeDPrG_qp1S9QhInl9r3G0cZx_16OvnTXORgA3n4/edit?usp=sharing
there is two sheets one with the old version of my layout called "OLD" and my new desired layout called "NEW"
thanks in advance to anyone able to help

This function hides a column whose top row date is less yesterday.
function hideColumnWhenTopRowDateIsBeforeYesterday() {
var ss=SpreadsheetApp.getActiveSpreadsheet();
var sh=ss.getSheetByName("Sheet1");
var rg=sh.getRange(1,1,1,sh.getLastColumn());
var vA=rg.getValues()[0];
var yesterday=new Date(new Date().getFullYear(),new Date().getMonth(),new Date().getDate()-1).valueOf();
vA.forEach(function(e,i){
if(new Date(e).valueOf()<yesterday) {
sh.hideColumns(i+1);
}
});
}
My Spreadsheet before hiding columns:
My Spreadsheet after hiding columns:

Related

Same variable for multiple sheets but only execute if export button on one sheet is pressed

I am trying to code an data export. The export is executed when a button is pressed and the script linked to the button will be executed. The data is transfered to a masterdata sheet.
The script is valid for 4 different sheets and i am trying to code it, so that i do not have to rename all the vaiables for each sheet.
I found some solution that i tried, by creating a variable with the sheet names and then call this variable in the following code.
Problem 1: Error "TypeError: Cannot read property 'copyTo' of null" occurs.
Problem 2: How to ensure that only the data from the sheet where the export button is pressed will be exported?
I tried a lot and cannot find a solution.
var sheetListArray = ["B1-Prozessfragen", "B2-Prozessfragen"];
var ss = SpreadsheetApp.getActiveSpreadsheet();
for( var k = 1 ; k <= sheetListArray.length ; k++)
ExportData1g (sheetListArray[k]);
PB1g (sheetListArray[k]);
function ExportData1g (sheetname) {
var result = SpreadsheetApp.getUi().alert("Fertig-Hacken gesetzt?", SpreadsheetApp.getUi().ButtonSet.OK_CANCEL); {
if (result === SpreadsheetApp.getUi().Button.OK) {
const ssh=ss.getSheetByName(sheetname);
const cell = ssh.getRange("CheckButton1").getValue();
if (cell == "1" || "0") {
(PB1g ());
}
else {return;} }
else {return;}
}
const ssh=ss.getSheetByName(sheetname);
var dataRange = ssh.getRange('CheckBox1');
var values = dataRange.getValues();
for (var i = 0; i < values.length; i++) {
for (var j = 0; j < values[i].length; j++) {
if (values[i][j] == true) {
values[i][j] = false;
}}
dataRange.setValues(values);
var commentRange = ssh.getRange ('ResetComment1');
var dataRange = ssh.getRange('EmptyBoxes1');
var values = dataRange.getValues();
for (var i = 0; i < values.length; i++) {
for (var j = 0; j < values[i].length; j++) {
if (values[i][j] == 1) {
values[i][j] = 0;
}
}
}
commentRange.clearContent();
dataRange.setValues(values);
} }
function PB1g(sheetname) {
const ssh=ss.getSheetByName(sheetname);
const tss=SpreadsheetApp.openById("1wMw5H48Fmc1R8WGy34d80x9-W996c9GNVuAD3-mFtVQ");
const tsh=tss.getSheetByName("PB");
const nsh=ssh.copyTo(tss);
var firstEmtyRow = tsh.getLastRow () + 1;
var timestamp = new Date();
tsh.appendRow([timestamp]);
nsh.getRange("CopytoMasterdata1").copyTo(tsh.getRange("B" + firstEmtyRow), {contentsOnly:true});
tss.deleteSheet(nsh); }

In the beginning, the script worked fine but it's getting slow with time as the number of rows is increasing

In the beginning, the script worked fine but it's getting slow with time as the number of rows is increasing.
Is there a way to optimize it or should I use some other tool?
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var datass = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Confidential- 1");
var activeCell = ss.getActiveCell();
if(activeCell.getColumn() == 4 && activeCell.getRow() > 1){
activeCell.offset(0,1).clearContent().clearDataValidations();
var makes = datass.getRange(1,1,1, datass.getLastColumn()).getValues();
var makeIndex = makes[0].indexOf(activeCell.getValue()) + 1;
if(makeIndex != 0){
var validationRange = datass.getRange(3, makeIndex, datass.getLastRow());
var validationRule = SpreadsheetApp.newDataValidation().requireValueInRange(validationRange).build();
activeCell.offset(0,1).setDataValidation(validationRule);
}
}
}

How do I auto populate row data based on criteria but have return values editable?

Hello I'm brand new to the script world!
Problem: Vlookup return is not editable.
I tried IndexMatch without success.
I am making a truck maintenance file. The trucks have hour and kilometer trackers that are updated hourly in sheets. Our goal is to enter truck unit number and have the date, hours, and kilometers populate our mechanics notes. From Data entry sheet a button will enter that data into each units maintenance page. Vlookup returned the right results but if an adjustment on date, hours, or kilometers needs to be made the cell can't be edited.
I am looking for a hand in setting this up.
I will share the sheet.
Search Key 'Data Entry A2'
Range 'Data Entry A8:C17'
Index 'Data Entry A8:A17'
Thanksenter link description here
function onEdit(e)
{
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Menu");
var activeCell = sheet.getActiveCell();
var col = activeCell.getColumn();
var row = 2;
if (col == 1 ) { // update when change in column 1, adapt if neededfunction
CopyRow() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuSheet = ss.getSheetByName("Menu");
var inventorySheet = ss.getSheetByName("Inventory");
menuSheet.getRange("C2:D2").clear();
var partNumber = menuSheet.getRange(2,1).getValue();
var lastRow = inventorySheet.getLastRow() + 1;
var foundRecord = false;
for(var j = 2; j < lastRow; j++)
{
if(inventorySheet.getRange(j,1).getValue() ==partNumber)
{
var nextRow = menuSheet.getRange(2,3);
var getCopyRange = inventorySheet.getRange('B' + j + ':C' + j);
getCopyRange.copyTo(menuSheet.getRange(2, 3));
foundRecord = true;
}
}
if(foundRecord == false)
{
menuSheet.getRange(5,1).setValue(['(NO RECORDS FOUND)']);
}
}
}

EPPlus two color conditional date format

I have a column with dates and I want to conditionally color any cell that is older that 2 week yellow, and any that is older than 90 days red. I can't figure out how to do that.
Should be able to just add the conditions like any other. You can use the TODAY() function in excel and subtract:
[TestMethod]
public void Conditional_Formatting_Date()
{
//https://stackoverflow.com/questions/56741642/epplus-two-color-conditional-date-format
var file = new FileInfo(#"c:\temp\Conditional_Formatting_Date.xlsx");
if (file.Exists)
file.Delete();
//Throw in some data
var dataTable = new DataTable("tblData");
dataTable.Columns.AddRange(new[] {
new DataColumn("Col1", typeof(DateTime)),
new DataColumn("Col3", typeof(string))
});
var rnd = new Random();
for (var i = 0; i < 100; i++)
{
var row = dataTable.NewRow();
row[0] = DateTime.Now.AddDays(-rnd.Next(1, 100));
row[1] = $"=TODAY() - A{i +1}";
dataTable.Rows.Add(row);
}
//Create a test file
using (var package = new ExcelPackage(file))
{
//Make the stylesheet
var ws = package.Workbook.Worksheets.Add("table");
var range = ws.Cells[1, 1].LoadFromDataTable(dataTable, false);
ws.Column(1).Style.Numberformat.Format = "mm-dd-yy";
ws.Column(1).AutoFit();
//Add the calc check
var count = 0;
foreach (DataRow row in dataTable.Rows)
ws.Cells[++count, 2].Formula = row[1].ToString();
//Add the conditions - order matters
var rangeA = range.Offset(0, 0, count, 1);
var condition90 = ws.ConditionalFormatting.AddExpression(rangeA);
condition90.Style.Font.Color.Color = Color.White;
condition90.Style.Fill.PatternType = ExcelFillStyle.Solid;
condition90.Style.Fill.BackgroundColor.Color = Color.Red;
condition90.Formula = "TODAY() - A1> 90";
condition90.StopIfTrue = true;
var condition14 = ws.ConditionalFormatting.AddExpression(rangeA);
condition14.Style.Font.Color.Color = Color.Black;
condition14.Style.Fill.PatternType = ExcelFillStyle.Solid;
condition14.Style.Fill.BackgroundColor.Color = Color.Yellow;
condition14.Formula = "TODAY() - A1> 14";
package.Save();
}
}
Which gives this in the output:
I am assuming that you have the column number of the date column and number of rows in your records. Also, the following loop is under assumption that the first row is your column header and records begin from second row. Change the loop counter's initialization and assignment accordingly.
int rowsCount; //get your no of rows
int dateColNumber; //Assign column number in excel file of your date column
string cellValue;
DateTime dateValue;
DateTime today = DateTime.Now;
double daysCount;
for(int i=1;i<rowsCount;i++)
{
cellValue = ws.Cells[i + 1, dateColNumber].Text.ToString(); //First row is header start from second
if(DateTime.TryParse(cellValue,out dateValue))
{
daysCount = (today - dateValue).Days;
if(daysCount>90)
{
ws.Cells[i + 1,dateColNumber].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
ws.Cells[i + 1,dateColNumber].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.Red);
}
else if(daysCount>14)
{
ws.Cells[i + 1, dateColNumber].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
ws.Cells[i + 1, dateColNumber].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.Yellow);
}
}
}

Google Apps Script Sheet Looping Issue

I'm having issues with the GAS code below. The purpose is to iterate through all available sheets and create the drop-down boxes/ validation rules I would need to make an easy-to-edit form.
The main issue is that the code only runs once per sheet and it never applies itself to any other sheet except the active one; ie. it won't cycle to the next available sheet.
function FailureSauce() {
var ss = SpreadsheetApp.getActive();
for(var n in ss.getSheets()) { // loop over all tabs in the spreadsheet
var sheet = ss.getSheets()[n]; // look at every sheet in spreadsheet
var option = new Array();
option[0]="☐";
option[1]="☑";
//var dv = sheet.getRange(myRange.getRow(),myRange.getColumn()+1).getValidation();
var dv = SpreadsheetApp.getActiveSheet().getRange(SpreadsheetApp.getActiveRange().getRow(),SpreadsheetApp.getActiveRange().getColumn()).getDataValidation();
var dv = SpreadsheetApp.newDataValidation();
//dv.setAllowInvalidData(false);
dv.setAllowInvalid(false);
dv.setHelpText("Please choose of the options given in the drop down box");
dv.requireValueInList(option, true);
for (var i = 9; i <= SpreadsheetApp.getActiveSpreadsheet().getLastRow(); i++) {
for (var y = 1; y < 4; y++) {
SpreadsheetApp.getActiveSheet().getRange(i,y).setFontFamily("Arial")
SpreadsheetApp.getActiveSheet().getRange(i,y).setFontSize(10)
if (SpreadsheetApp.getActiveSheet().getRange(i,y).isBlank()) {
//SpreadsheetApp.getActiveSheet().getRange(i,y).setValue('=if(A2=1,image("http://i.stack.imgur.com/GChKZ.jpg"),image("http://i.stack.imgur.com/yQalm.jpg"))');
//sheet.getRange(SpreadsheetApp.getActiveSheet().getRow(),SpreadsheetApp.getActiveSheet().getColumn()).setDataValidation(dv.build());
SpreadsheetApp.getActiveSheet().getRange(i,y).setDataValidation(dv.build());
}
if (SpreadsheetApp.getActiveSheet().getRange(i,y).getValues() == "a") {
//SpreadsheetApp.getActiveSheet().getRange(i,y).setValue('=image("http://i.stack.imgur.com/GChKZ.jpg")');
SpreadsheetApp.getActiveSheet().getRange(i,y).setDataValidation(dv.build());
SpreadsheetApp.getActiveSheet().getRange(i,y).setValue("☑")
}
}
}
}
}
You should probably replace SpreadsheetApp.getActiveSheet() with your variable sheet.
function FailureSauce() {
var dv,option,ss,sheet;
ss = SpreadsheetApp.getActiveSpreadsheet();
for(var n in ss.getSheets()){// loop over all tabs in the spreadsheet
sheet = ss.getSheets()[n];// look at every sheet in spreadsheet
Logger.log('name: ' + sheet.getName());
option = new Array();
option[0]="☐";
option[1]="☑";
// var dv = sheet.getRange(myRange.getRow(),myRange.getColumn()+1).getValidation();
dv = sheet.getRange(SpreadsheetApp.getActiveRange().getRow(),SpreadsheetApp.getActiveRange().getColumn()).getDataValidation();
dv = SpreadsheetApp.newDataValidation();
// dv.setAllowInvalidData(false);
dv.setAllowInvalid(false);
dv.setHelpText("Please choose of the options given in the drop down box");
dv.requireValueInList(option, true);
for (var i = 9; i <= SpreadsheetApp.getActiveSpreadsheet().getLastRow(); i++) {
for (var y = 1; y < 4; y++) {
sheet.getRange(i,y).setFontFamily("Arial")
sheet.getRange(i,y).setFontSize(10)
if (sheet.getRange(i,y).isBlank()){
// sheet.getRange(i,y).setValue('=if(A2=1,image("http://i.stack.imgur.com/GChKZ.jpg"),image("http://i.stack.imgur.com/yQalm.jpg"))');
// sheet.getRange(sheet.getRow(),sheet.getColumn()).setDataValidation(dv.build());
sheet.getRange(i,y).setDataValidation(dv.build());
}
if (sheet.getRange(i,y).getValues() == "a"){
// sheet.getRange(i,y).setValue('=image("http://i.stack.imgur.com/GChKZ.jpg")');
sheet.getRange(i,y).setDataValidation(dv.build());
sheet.getRange(i,y).setValue("☑")
}
}
}
}
}