Reputation: 11
Dear Wonderful Scripters,
Apologies for not knowing all the lingo, I'm a novice at best but I've hit the wall. I am trying to hide/show columns based on two values in different cells.
I have a sheet named "Start" which has a value that changes (Year) in O2. This corresponds to a column on a sheet named "Subjects" (see pic). Subjects has a list of subjects and columns labelled "Prep, Year 1-2, Year 3-4 and Year 5-6". I would like to script a solution that checks the value on Start and then reads the column on Subjects for 1s and 0s and shows/hides columns on another sheet named "Reports".
For example, if O2 on Start says Year 1-2, then the script looks at Subjects (D1) and then shows or hides (1 or 0) columns on Reports that correspond with those subjects (eg Preps on have IPDIP so if the value is Year 1-2, then the column on Reports will be hidden. There is more than one column on Reports that will be hidden or shown.
I'm currently using this script:
function ShowHideSubjects() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Reports");
sheet.showColumns(1, sheet.getMaxColumns())
var condition = sheet.getRange("Subjects!C2").getValue();
if (condition = 1) {
sheet.showColumns(10,1)
}
var condition = sheet.getRange("Subjects!C2").getValue();
if (condition = 0) {
sheet.hideColumns(10,1)
}
}
Here's some pics to explain.
[Value on Start][1]
Your help would be greatly appreciated. This Google Spreadsheet currently saves our school $1000s a year and it would be awesome to get this sorted out.
Peace and thanks,
Wayne
Upvotes: 1
Views: 281
Reputation: 64062
function onOpen()
{
SpreadsheetApp.getUi().createMenu('My Tools')
.addItem('ShowHideSubjects','ShowHideSubjects')
.addToUi();
}
function ShowHideSubjects()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var reportsSheet = ss.getSheetByName('Reports');
var subjectsSheet = ss.getSheetByName('Subjects')
var startSheet = ss.getSheetByName('Start');
var startSubjectsRange = startSheet.getRange('O2');
var reportsSheetDataRange = reportsSheet.getDataRange();
var reportsSheetDataArray = reportsSheetDataRange.getValues();
var reportsSheetDataRangeLastRow = reportsSheetDataRange.getLastRow();
var reportsSheetDataRangeLastColumn = reportsSheetDataRange.getLastColumn();
for(var i = 0;i < reportsSheetDataRangeLastRow;i++)
{
for(var j = 0;j < reportsSheetDataRangeLastColumn;j ++)
{
if(reportsSheetDataArray[i][j] == 'IPDIP')
{
var ipdipRow = i + 1;
var ipdipCol = j + 1;
break;
}
}
}
var reportsNumColumns = reportsSheetDataRange.getLastColumn() - ipdipCol + 1
//check that its the right reports range
//reportsSheet.setActiveSelection(reportsSheet.getRange(ipdipRow, ipdipCol, 1 , reportsNumColumns));
var reportsHeaderRange = reportsSheet.getRange(ipdipRow, ipdipCol, 1 , reportsNumColumns);
var subjectsSheetDataRange = subjectsSheet.getDataRange();
var subjectsSheetDataArray = subjectsSheetDataRange.getValues();
var subjectsSheetDataRangeLastRow = subjectsSheetDataRange.getLastRow();
var subjectsSheetDataRangeLastColumn = subjectsSheetDataRange.getLastColumn();
for(var i = 0;i < subjectsSheetDataRangeLastRow;i++)
{
for(var j = 0;j < subjectsSheetDataRangeLastColumn;j ++)
{
if(subjectsSheetDataArray[i][j] == 'Subjects')
{
var subjectsRow = i + 1;
var subjectsCol = j + 1;
break;
}
}
}
//check that its the right subjects range
//subjectsSheet.setActiveSelection(subjectsSheet.getRange(subjectsRow, subjectsCol,subjectsSheetDataRange.getLastRow() - subjectsRow + 1 ,subjectsSheetDataRange.getLastColumn() - subjectsCol + 1));
var subjectsShowHideHeaderRange = subjectsSheet.getRange(subjectsRow, subjectsCol, 1 ,subjectsSheetDataRange.getLastColumn() - subjectsCol + 1);
var subjectsShowHideHeaderArray = subjectsShowHideHeaderRange.getValues();
var subjectsShowHideRange = subjectsSheet.getRange(subjectsRow, subjectsCol,subjectsSheetDataRange.getLastRow() - subjectsRow + 1 ,subjectsSheetDataRange.getLastColumn() - subjectsCol + 1);
//checked subjectsShowHideRange
//subjectsSheet.setActiveSelection(subjectsShowHideRange);
var w = subjectsShowHideHeaderRange.getWidth();
var startString = startSubjectsRange.getValue();
for(var i = 0;i < w;i++)
{
if(subjectsShowHideHeaderArray[0][i] == startString)
{
var subjectsShowHideColumn = subjectsCol + i;
break;
}
}
//checked the subjectsShowHideColumn
//SpreadsheetApp.getUi().alert( startSubjectsRange.getValue() + ' is column ' + subjectsShowHideColumn + ' on the subjects page. And subjects is on column ' + subjectsCol + '.');
//Checked the subjectsShowHideRange
//subjectsSheet.setActiveSelection(subjectsShowHideRange);
var subjectsShowHideArray = subjectsShowHideRange.getValues();
var subjectsShowHideRangeHeight = subjectsShowHideRange.getHeight();
//for(var i = 0;i < subjectsShowHideRangeHeight;i++)
for(var i = subjectsShowHideRangeHeight -1;i >= 0;i--)
{
var subject = subjectsShowHideArray[i][0];
var show = subjectsShowHideArray[i][subjectsShowHideColumn-subjectsCol];
var showhidecolsS=reportsColumnHeaderMatch(ipdipRow,ipdipCol,reportsNumColumns,subject);
if(showhidecolsS)
{
var showhidecolsA=showhidecolsS.split(',');
if(showhidecolsA)
{
for(var j = 0; j < showhidecolsA.length; j++)
{
columnsShowHide(showhidecolsA[j],show);
}
}
}
}
}
function columnsShowHide(column, show)
{
var column = (typeof(column) !== 'undefined')? column: 0;
var show = (typeof(show) !== 'undefined')? show: 1;
if(column == 0)
{
SpreadsheetApp.getUi().alert('Error: The column parameter passed to columnsShowHide is undefined.');
return;
}
else
{
switch(show)
{
case 1:
SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Reports').showColumns(column);
//SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Reports').getRange(1,column,10,1).setBackground('yellow');
break;
case 0:
SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Reports').hideColumns(column);
//SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Reports').getRange(1,column,10,1).setBackground('white');
break;
default:
SpreadsheetApp.getUi().alert('Show parameter is out of range not 0 or 1 in function columnsShowHide');
}
}
}
function reportsColumnHeaderMatch(row, col, numcolumns, subject)
{
var sht = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Reports');
var rng = sht.getRange(row, col, 1, numcolumns);
var rngA = rng.getValues();
var result = '';
var firsttime = true;
for(var i = 0;i < numcolumns;i++)
{
//var s = rngA[0][i].toString();
var s = rngA[0][i];
var re = new RegExp('^' + subject);
if(s.match(re))
{
if(!firsttime)result += ',';
result += col + i;
firsttime = false;
}
}
return result;
}
function dispStatus(title,html,width,height)
{
// Display a modeless dialog box with custom HtmlService content.
var title = typeof(title) !== 'undefined' ? title : 'No Title Provided';
var width = typeof(width) !== 'undefined' ? width : 250;
var height = typeof(height) !== 'undefined' ? height : 300;
var html = typeof(html) !== 'undefined' ? html : '<p>No html provided.</p>';
var htmlOutput = HtmlService
.createHtmlOutput(html)
.setWidth(width)
.setHeight(height);
SpreadsheetApp.getUi().showModelessDialog(htmlOutput, title);
}
I have a working version but I ran into a problem. I'm using a regular expression RegExp('^' + subject). What this allows me to do is to build the regular expression on the fly. When the subject is IPDIP the regular expression ^IPDIP matches all of the characters of the IPDIP column header and since the second row of Year 1-2 is 0 then column IPDIP is turned off but then the next subject is IPD and the regular expression ^IPD also matches IPDIP and the third row of Year 1-2 now turns off IPDIP which is probably a problem. I was planning on using this technique to match the rest of the columns because the subjects are only the first three letters of the rest of the column headers and that would be a great way to catch them. So I guess the question is do you want IPDIP on or off in for the Year 1-2 reports.
Are all of the Reports column header names six characters or greater? I could take advantage of that because IPDIP is only 5 characters. So I could apply my regular expression only to headers that are 6 characters or greater. But I need your input on that because I'm guessing that the actual Reports sheet is probably a little wider than the one I see.
I guess another solution could be to work my way up through from the bottom of the subjects column to the top then IPDIP would always be the 5 character match.
I just noticed that we have the same problem with ICT and ICTICT.
For now I decided to just reverse the order of going through the subjects column from bottom to top. As long as you always put the longest strings that have overlapping matches on the top you should be okay.
Upvotes: 1
Reputation: 11
Works exactly as requested, first try :-) Thanks to Cooper for the hard work.
function onOpen()
{
SpreadsheetApp.getUi().createMenu('My Tools')
.addItem('ShowHideSubjects','ShowHideSubjects')
.addToUi();
}
function ShowHideSubjects()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var reportsSheet = ss.getSheetByName('Reports');
var subjectsSheet = ss.getSheetByName('Subjects')
var startSheet = ss.getSheetByName('Start');
var startSubjectsRange = startSheet.getRange('O2');
var reportsSheetDataRange = reportsSheet.getDataRange();
var reportsSheetDataArray = reportsSheetDataRange.getValues();
var reportsSheetDataRangeLastRow = reportsSheetDataRange.getLastRow();
var reportsSheetDataRangeLastColumn = reportsSheetDataRange.getLastColumn();
for(var i = 0;i < reportsSheetDataRangeLastRow;i++)
{
for(var j = 0;j < reportsSheetDataRangeLastColumn;j ++)
{
if(reportsSheetDataArray[i][j] == 'IPDIP')
{
var ipdipRow = i + 1;
var ipdipCol = j + 1;
break;
}
}
}
var reportsNumColumns = reportsSheetDataRange.getLastColumn() - ipdipCol + 1
//check that its the right reports range
//reportsSheet.setActiveSelection(reportsSheet.getRange(ipdipRow, ipdipCol, 1 , reportsNumColumns));
var reportsHeaderRange = reportsSheet.getRange(ipdipRow, ipdipCol, 1 , reportsNumColumns);
var subjectsSheetDataRange = subjectsSheet.getDataRange();
var subjectsSheetDataArray = subjectsSheetDataRange.getValues();
var subjectsSheetDataRangeLastRow = subjectsSheetDataRange.getLastRow();
var subjectsSheetDataRangeLastColumn = subjectsSheetDataRange.getLastColumn();
for(var i = 0;i < subjectsSheetDataRangeLastRow;i++)
{
for(var j = 0;j < subjectsSheetDataRangeLastColumn;j ++)
{
if(subjectsSheetDataArray[i][j] == 'Subjects')
{
var subjectsRow = i + 1;
var subjectsCol = j + 1;
break;
}
}
}
//check that its the right subjects range
//subjectsSheet.setActiveSelection(subjectsSheet.getRange(subjectsRow, subjectsCol,subjectsSheetDataRange.getLastRow() - subjectsRow + 1 ,subjectsSheetDataRange.getLastColumn() - subjectsCol + 1));
var subjectsShowHideHeaderRange = subjectsSheet.getRange(subjectsRow, subjectsCol, 1 ,subjectsSheetDataRange.getLastColumn() - subjectsCol + 1);
var subjectsShowHideHeaderArray = subjectsShowHideHeaderRange.getValues();
var subjectsShowHideRange = subjectsSheet.getRange(subjectsRow, subjectsCol,subjectsSheetDataRange.getLastRow() - subjectsRow + 1 ,subjectsSheetDataRange.getLastColumn() - subjectsCol + 1);
//checked subjectsShowHideRange
//subjectsSheet.setActiveSelection(subjectsShowHideRange);
var w = subjectsShowHideHeaderRange.getWidth();
var startString = startSubjectsRange.getValue();
for(var i = 0;i < w;i++)
{
if(subjectsShowHideHeaderArray[0][i] == startString)
{
var subjectsShowHideColumn = subjectsCol + i;
break;
}
}
//checked the subjectsShowHideColumn
//SpreadsheetApp.getUi().alert( startSubjectsRange.getValue() + ' is column ' + subjectsShowHideColumn + ' on the subjects page. And subjects is on column ' + subjectsCol + '.');
//Checked the subjectsShowHideRange
//subjectsSheet.setActiveSelection(subjectsShowHideRange);
var subjectsShowHideArray = subjectsShowHideRange.getValues();
var subjectsShowHideRangeHeight = subjectsShowHideRange.getHeight();
//for(var i = 0;i < subjectsShowHideRangeHeight;i++)
for(var i = subjectsShowHideRangeHeight -1;i >= 0;i--)
{
var subject = subjectsShowHideArray[i][0];
var show = subjectsShowHideArray[i][subjectsShowHideColumn-subjectsCol];
var showhidecolsS=reportsColumnHeaderMatch(ipdipRow,ipdipCol,reportsNumColumns,subject);
if(showhidecolsS)
{
var showhidecolsA=showhidecolsS.split(',');
if(showhidecolsA)
{
for(var j = 0; j < showhidecolsA.length; j++)
{
columnsShowHide(showhidecolsA[j],show);
}
}
}
}
}
function columnsShowHide(column, show)
{
var column = (typeof(column) !== 'undefined')? column: 0;
var show = (typeof(show) !== 'undefined')? show: 1;
if(column == 0)
{
SpreadsheetApp.getUi().alert('Error: The column parameter passed to columnsShowHide is undefined.');
return;
}
else
{
switch(show)
{
case 1:
SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Reports').showColumns(column);
//SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Reports').getRange(1,column,10,1).setBackground('yellow');
break;
case 0:
SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Reports').hideColumns(column);
//SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Reports').getRange(1,column,10,1).setBackground('white');
break;
default:
SpreadsheetApp.getUi().alert('Show parameter is out of range not 0 or 1 in function columnsShowHide');
}
}
}
function reportsColumnHeaderMatch(row, col, numcolumns, subject)
{
var sht = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Reports');
var rng = sht.getRange(row, col, 1, numcolumns);
var rngA = rng.getValues();
var result = '';
var firsttime = true;
for(var i = 0;i < numcolumns;i++)
{
//var s = rngA[0][i].toString();
var s = rngA[0][i];
var re = new RegExp('^' + subject);
if(s.match(re))
{
if(!firsttime)result += ',';
result += col + i;
firsttime = false;
}
}
return result;
}
function dispStatus(title,html,width,height)
{
// Display a modeless dialog box with custom HtmlService content.
var title = typeof(title) !== 'undefined' ? title : 'No Title Provided';
var width = typeof(width) !== 'undefined' ? width : 250;
var height = typeof(height) !== 'undefined' ? height : 300;
var html = typeof(html) !== 'undefined' ? html : '<p>No html provided.</p>';
var htmlOutput = HtmlService
.createHtmlOutput(html)
.setWidth(width)
.setHeight(height);
SpreadsheetApp.getUi().showModelessDialog(htmlOutput, title);
}
Upvotes: 0