Как раскрасить все слова в результатах, содержащие текст, который я искал с помощью функции запроса?
В Google Sheets я использую «функцию запроса» для поиска в столбце C на листе 1 текста в ячейке B2. Как я могу использовать сценарии Google Apps для раскрашивания всех слов в результатах, содержащих искомый мной текст? И если я изменю текст в B2, результат запроса изменится, и сценарий приложения перекрасит новые слова в результатах, содержащих новый текст.
Это ссылка на образец таблицы, в которой объясняется, что мне нужно:
Эта картинка объясняет, что я хочу сделать:
Вот фрагмент, который вы можете попробовать:
function underlineWord() {
let sheet = SpreadsheetApp.getActiveSheet();
let valueToSearch = sheet.getRange("B1").getValue();
let data = sheet.getRange("G4:G").getValues().flat().filter(el => el != "");
let style = SpreadsheetApp.newTextStyle();
style.setForegroundColor("#ea4335");
let buildStyle = style.build();
let richTextValues = [];
for (let i = 0; i < data.length; i++) {
let startIndex = data[i].indexOf(valueToSearch);
let wordLength = valueToSearch.length;
let richText = SpreadsheetApp.newRichTextValue();
richText.setText(data[i]);
richText.setTextStyle(startIndex, startIndex + wordLength, buildStyle);
let format = richText.build();
richTextValues.push([format]);
}
sheet.getRange(`G4:G${richTextValues.length + 1}`).setRichTextValues(richTextValues);
}
Если вам нужно другое форматирование или информация, вы можете обратиться к: Класс RichTextValueBuilder
=QUERY(Sheet1!A2:C,"where C contains '"&B1&"'")
. В этом случае при изменении стиля текста в столбце «С» скриптом и ручной операцией возникает ошибка, поскольку значения, заданные формулой, не могут быть перезаписаны. В вашем показании ожидаемого результата я думаю, что столбец "Г" проставлен без формулы. При этом стиль текста может быть изменен.Чтобы избежать этой проблемы, я хотел бы предложить следующий обходной путь. Шаги этого обходного пути следующие.
rare
, в ячейку «B1» листа «Поиск».=QUERY(Sheet1!A2:C,"where C contains '"&B1&"'")
в ячейку «А4».С помощью этих шагов, когда вы вводите текст для поиска, стили текста столбца «C» можно изменить.
Когда этот обходной путь отражен в примере сценария, он выглядит следующим образом.
function onEdit(e) {
const { range } = e;
const sheet = range.getSheet();
if (sheet.getSheetName() != "Search" || range.columnStart != 2 || range.rowStart != 1) return;
const searchValue = range.getValue();
// Clear cells "A4:C".
const dataRange = sheet.getRange("A4:C" + sheet.getLastRow()).clearContent();
// Put your formula `=QUERY(Sheet1!A2:C,"where C contains '"&B1&"'")` in to cell "A4".
sheet.getRange("A4").setFormula(`=QUERY(Sheet1!A2:C,"where C contains '"&B1&"'")`);
SpreadsheetApp.flush();
// Convert the formula to text.
dataRange.copyTo(dataRange, { contentsOnly: true });
// Set text style using the search text to column "C".
const style = SpreadsheetApp.newTextStyle().setBold(true).setForegroundColor("red").build();
const rt = dataRange.getValues().map(([, , c]) => {
const r = SpreadsheetApp.newRichTextValue().setText(c);
[...c.matchAll(new RegExp(`${searchValue}.*?\\b`, "g"))].forEach(o =>
r.setTextStyle(o.index, o.index + o[0].length, style)
);
return [r.build()];
});
dataRange.offset(0, 2, rt.length, 1).setRichTextValues(rt);
}
Когда я протестировал этот сценарий с использованием предоставленной вами электронной таблицы, был получен следующий результат.
В этом скрипте используется простой триггер onEdit
. Если время обработки скрипта превышает 30 секунд, переименуйте имя функции с onEdit
на installedOnEdit
. Затем установите триггер OnEdit на installedOnEdit
и проверьте его еще раз. При этом максимальное время выполнения составляет 6 минут.
Этот сценарий можно использовать в предоставленной вами электронной таблице. При изменении электронной таблицы этот сценарий может оказаться недоступным для использования. Пожалуйста, будьте осторожны с этим.
Когда я увидел ваш вопрос, я подумал, что вы, возможно, захотите автоматически запускать скрипт, когда текст поиска помещается в ячейку «B1» листа «Поиск». Но из вашего следующего ответа,
но я все еще получаю эту ошибку: TypeError: Невозможно деструктурировать свойство «диапазон» «e», поскольку оно не определено. onEdit
Если вы хотите напрямую запустить сценарий с помощью редактора сценариев, кнопки, пользовательского меню и т. д., как насчет следующего примера сценария?
При использовании этого сценария выполните следующую последовательность действий.
rare
, в ячейку «B1» листа «Поиск».sample
в редакторе скриптов.Таким образом, сценарий работает с предоставленной вами электронной таблицей.
function sample() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const srcSheet = ss.getSheetByName("Sheet1");
const srcValues = srcSheet.getRange("A2:C" + srcSheet.getLastRow()).getValues();
const dstSheet = ss.getSheetByName("Search");
const searchValue = dstSheet.getRange("B1").getValue();
const dstValues = srcValues.filter(([, , c]) => c.includes(searchValue));
if (dstValues.length == 0) return;
dstSheet.getRange("A4:C" + dstSheet.getLastRow()).clearContent();
const dstRange = dstSheet.getRange(4, 1, dstValues.length, dstValues[0].length);
dstRange.setValues(dstValues);
const style = SpreadsheetApp.newTextStyle().setBold(true).setForegroundColor("red").build();
const rt = dstValues.map(([, , c]) => {
const r = SpreadsheetApp.newRichTextValue().setText(c);
[...c.matchAll(new RegExp(`${searchValue}.*?\\b`, "g"))].forEach(o =>
r.setTextStyle(o.index, o.index + o[0].length, style)
);
return [r.build()];
});
dstRange.offset(0, 2, rt.length, 1).setRichTextValues(rt);
}
При запуске этого сценария получается тот же результат, что и вышеприведенный. Но в этом случае необходимо запустить функцию вручную. Пожалуйста, будьте осторожны с этим.
Спасибо за вашу помощь, но я все еще получаю эту ошибку: TypeError: Cannot destructure property 'range' of 'e' as it is undefined. onEdit @ Code.gs:2
@Mergen Спасибо за ответ. О Thanks for your help, but I still get this error: TypeError: Cannot destructure property 'range' of 'e' as it is undefined. onEdit @ Code.gs:2
, как ты запустил мой скрипт? Если вы напрямую запустите мой скрипт, возникнет ошибка Cannot destructure property 'range' of 'e' as it is undefined.
из-за отсутствия объекта события. Пожалуйста, будьте осторожны с этим.
@Mergen Судя по вашему вопросу, мой скрипт автоматически запускается, когда текст поиска помещается в ячейку «B1» листа «Поиск». Итак, поместите текст поиска в ячейку «B1» листа «Поиск».
@Mergen Из but I still get this error: TypeError: Cannot destructure property 'range' of 'e' as it is undefined. onEdit
я добавил еще один пример сценария. Этот сценарий можно запустить вручную.
Спасибо за вашу помощь, но я все равно получаю эту ошибку:
Exception: Illegal argument. underlineWord @ Code.gs:14