Appsスクリプトなし
Apps Scriptなしで新しい関数を作成することはできません。プロセスを合理化する唯一の方法は、より多くのセルをどこかに配置し、それらを参照することです。
例:「Weight」などの各ヘッダーの下に、次のコマンドを入力します
=regexextract(address(1, column()), "[A-Z]+")
これにより、列文字がヘッダーの下に配置されます。ヘッダーの名前付き範囲に文字のある行を含めます。クエリ文字列では、
hlookup("Weight", Headers, 2, 0)
目には簡単です
SUBSTITUTE(ADDRESS(1,MATCH("Weight", Headers, 0),4), "1", "")
Apps Scriptを使用
範囲(名前付きまたはそれ以外)をカスタム関数に渡すと、値が渡されます。シート内の位置に関する情報はありません。しかし、私は解決策を見つけました:の最初の引数からヘッダーの場所を推測しますquery
。それ自体繰り返しだった「ヘッダー」を含める必要はありません。
バージョン1:クエリ範囲に含まれるヘッダー
クエリに渡される範囲にヘッダー行を含めることを好み、ヘッダー行の数をの3番目の引数として指定しますquery
。これにより、データをヘッダーとして誤って解釈すること、またはその逆を回避できます。例えば:
=QUERY(A1:F13, "select "&GetHeader("Type")&" where ("&GetHeader("Version")&" = 'Version 1') and ("&GetHeader("Type")&" <> 'Type')", 2)
上記のクエリで使用するカスタム関数は次のとおりです。
function getHeader(name) {
var sheet = SpreadsheetApp.getActiveSheet();
var formula = SpreadsheetApp.getActiveRange().getFormula();
var args = formula.match(/\w+:\w+(?=[ ,])/);
var range = sheet.getRange(args[0]);
var firstRow = range.offset(0, 0, 1, range.getWidth());
var headers = firstRow.getValues();
for (var i = 0; i < headers[0].length; i++) {
if (headers[0][i] == name) {
var notation = range.getCell(1, i+1).getA1Notation();
var column = notation.replace(/\d/, '');
return column;
}
}
return 'Not found';
}
関数は、呼び出し元のセルから数式を取得します。正規表現で数式の最初の範囲引数を抽出します。次に、指定された文字列を検索して、ヘッダー行であると想定して、この範囲の最初の行を調べます。文字列を含むセルのA1表記を取得し、その行部分を削除して、結果を返します。
バージョン2:行1から取得されたヘッダー
クエリの引数の行に関係なく、ヘッダーがシートの最初の行から取得される代替バージョン。交換するだけ
var firstRow = range.offset(0, 0, 1, range.getWidth());
と
var firstRow = sheet.getRange(1, range.getColumn(), 1, range.getWidth());
このバージョンでは、使用できます
=QUERY(A3:F13, "select "&GetHeader("Type")&" where ("&GetHeader("Version")&" = 'Version 1') and ("&GetHeader("Type")&" <> 'Type')")