Раскраска искомого слова в Google Sheets

Как раскрасить все слова в результатах, содержащие текст, который я искал с помощью функции запроса?

В Google Sheets я использую «функцию запроса» для поиска в столбце C на листе 1 текста в ячейке B2. Как я могу использовать сценарии Google Apps для раскрашивания всех слов в результатах, содержащих искомый мной текст? И если я изменю текст в B2, результат запроса изменится, и сценарий приложения перекрасит новые слова в результатах, содержащих новый текст.

Это ссылка на образец таблицы, в которой объясняется, что мне нужно:

Образец таблицы

Эта картинка объясняет, что я хочу сделать:

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
65
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вот фрагмент, который вы можете попробовать:

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

Спасибо за вашу помощь, но я все равно получаю эту ошибку: Exception: Illegal argument. underlineWord @ Code.gs:14

Mergen 18.07.2024 12:59
Ответ принят как подходящий

Точки модификации:

  • Из вашего изображения я заметил, что в вашей ситуации значения столбца «C» задаются с использованием такой формулы, как =QUERY(Sheet1!A2:C,"where C contains '"&B1&"'"). В этом случае при изменении стиля текста в столбце «С» скриптом и ручной операцией возникает ошибка, поскольку значения, заданные формулой, не могут быть перезаписаны. В вашем показании ожидаемого результата я думаю, что столбец "Г" проставлен без формулы. При этом стиль текста может быть изменен.

Чтобы избежать этой проблемы, я хотел бы предложить следующий обходной путь. Шаги этого обходного пути следующие.

  1. Поместите текст для поиска, например rare, в ячейку «B1» листа «Поиск».
  2. Очистить ячейки «A4:C».
  3. Введите формулу =QUERY(Sheet1!A2:C,"where C contains '"&B1&"'") в ячейку «А4».
  4. Преобразуйте формулу в текст.
  5. Установите стиль текста, используя текст поиска в столбце «C».

С помощью этих шагов, когда вы вводите текст для поиска, стили текста столбца «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

Если вы хотите напрямую запустить сценарий с помощью редактора сценариев, кнопки, пользовательского меню и т. д., как насчет следующего примера сценария?

При использовании этого сценария выполните следующую последовательность действий.

  1. Скопируйте и вставьте следующий сценарий в редактор сценариев предоставленной электронной таблицы и сохраните его.
  2. Введите текст для поиска, например rare, в ячейку «B1» листа «Поиск».
  3. Запустите функцию 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 18.07.2024 12:54

@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. из-за отсутствия объекта события. Пожалуйста, будьте осторожны с этим.

Tanaike 18.07.2024 14:09

@Mergen Судя по вашему вопросу, мой скрипт автоматически запускается, когда текст поиска помещается в ячейку «B1» листа «Поиск». Итак, поместите текст поиска в ячейку «B1» листа «Поиск».

Tanaike 18.07.2024 14:09

@Mergen Из but I still get this error: TypeError: Cannot destructure property 'range' of 'e' as it is undefined. onEdit я добавил еще один пример сценария. Этот сценарий можно запустить вручную.

Tanaike 18.07.2024 14:22

Другие вопросы по теме