列选择器
这是代码
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);
}
小问题
我有一个工作版本,但我遇到了问题。我正在使用正则表达式 RegExp('^' + subject)。这允许我做的是动态构建正则表达式。当主题是 IPDIP 时,正则表达式 ^IPDIP 匹配 IPDIP 列标题的所有字符,并且由于第 1-2 年的第二行是 0,因此关闭 IPDIP 列,但下一个主题是 IPD 和正则表达式 ^ IPD 也与 IPDIP 匹配,并且第 1-2 年的第三行现在关闭 IPDIP,这可能是一个问题。我计划使用这种技术来匹配其余的列,因为主题只是其余列标题的前三个字母,这将是捕捉它们的好方法。所以我想问题是您希望在 1-2 年的报告中打开还是关闭 IPDIP。
所有报告列标题名称是否都包含六个或更多字符?我可以利用这一点,因为 IPDIP 只有 5 个字符。所以我只能将我的正则表达式应用于 6 个字符或更大的标题。但我需要您对此提供意见,因为我猜测实际的报告表可能比我看到的要宽一些。
我想另一种解决方案可能是从主题列的底部向上移动到顶部,然后 IPDIP 将始终是 5 个字符匹配。
我刚刚注意到我们在 ICT 和 ICTICT 方面存在同样的问题。
现在我决定将主题列从下到上的顺序颠倒过来。只要您始终将具有重叠匹配项的最长字符串放在顶部,就可以了。
让你知道
我对这段代码所做的一件事是使表格的来源成为主题页面上的主题标题和报告页面上的 IPDIP 标题的位置。因此,这使您可以移动表格(即在当前数据的左侧和上方添加列)。该程序根据这两个关键位置确定数据的位置,并自动重新调整。另一种说法是,它不假设表中的第一行/列是行/列 1/A