Google (Docs) Apps Script - Невозможно проверить, находится ли курсор на именованном диапазоне - PullRequest
1 голос
/ 09 июля 2019

Я вставляю текст в документ, и каждая вставка текста добавляется в именованный диапазон, чтобы я мог просмотреть их все с getNamedRanges(NAME) и getNamedRangesById(ID).

Теперь мне нужно проверить,текущая позиция курсора находится в именованном диапазоне, и мне еще предстоит выяснить, как.

Этот пост похож: Как определить именованный диапазон от позиции в Документах Google до скрипта Google Apps

Но когда курсор находится в именованном диапазоне cursor.getElement() возвращает Text объект, а не именованный диапазон.

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

Ответы [ 2 ]

1 голос
/ 10 июля 2019
  • Вы хотите подтвердить, находится ли текущая позиция курсора внутри в namedRange в Документе Google.
  • Вы хотите добиться этого с помощью Google Apps Script.

Если мое понимание верно, как насчет этого примера сценария? Пожалуйста, подумайте об этом как об одном из нескольких ответов.

Обход:

В этом обходном пути я проверял, включена ли позиция курсора в namedRange, сравнивая индексы абзаца namedRange и позиции курсора.

Расход:

Ход выполнения сценария следующий.

  1. Получить индексы абзаца namedRange.
    • В этом примере сценария, из вашего вопроса, используется namedRange ID.
    • В этом случае может быть несколько абзацев, включая таблицу, список и т. Д. Таким образом, все индексы в namedRange извлекаются.
  2. Получить индекс абзаца позиции курсора.
  3. Получить индекс абзаца выбранного диапазона.
    • Этот пример сценария также проверяет, находится ли выбранный диапазон в namedRange. Потому что, когда текст выделен, cursor становится null.
  4. Если курсор или выбранный диапазон остаются в namedRange, myFunction() возвращает true.
    • Если курсор или выбранный диапазон не остаются в namedRange, myFunction() возвращает false.
    • Также вы можете подтвердить это в журнале.

Пример сценария:

Перед использованием этого скрипта, пожалуйста, установите namedRange ID.

function myFunction() {
  var nameRangeId = "###"; // Please set namedRange ID here.

  var getIndex = function(doc, e) {
    while (e.getParent().getType() != DocumentApp.ElementType.BODY_SECTION) e = e.getParent();
    return doc.getBody().getChildIndex(e);
  };
  var doc = DocumentApp.getActiveDocument();

  // For namedRange
  var namedRange = doc.getNamedRangeById(nameRangeId);
  if (namedRange) {
    var indexOfNamedRange = namedRange.getRange().getRangeElements().map(function(e) {return getIndex(doc, e.getElement())});
  } else {
    throw new Error("No namedRange.");
  }

  var name = namedRange.getName();

  // For cursor
  var cursor = doc.getCursor();
  if (cursor) {
    var indexOfCursor = getIndex(doc, cursor.getElement());
    if (~indexOfNamedRange.indexOf(indexOfCursor)) {
      Logger.log("Inside of %s", name);
      return true;
    }
    Logger.log("Outside of %s", name);
    return false;
  }

  // For select
  var select = doc.getSelection();
  if (select) {
    var indexOfSelect = select.getRangeElements().map(function(e) {return getIndex(doc, e.getElement())});
    if (indexOfSelect.some(function(e) {return ~indexOfNamedRange.indexOf(e)})) {
      Logger.log("Inside of %s", name);
      return true;
    }
    Logger.log("Outside of %s", name);
    return false;
  }

  throw new Error("No cursor and select.");
}

Примечание:

  • В этом сценарии, когда текст выбран в Документе, позиция курсора не может быть получена. Поэтому я добавил функцию проверки выбранного диапазона. Если вы не хотите проверять выбранный диапазон, удалите скрипт // For select.
  • В этом сценарии, даже только один индекс выбранного диапазона включен в namedRange, true возвращается. Об этом, пожалуйста, измените для вашей ситуации.
  • На данном этапе этот сценарий не предполагает разделы верхнего и нижнего колонтитула.

Ссылки:

Если я неправильно понял ваш вопрос, а это не то направление, которое вы хотите, я прошу прощения.

1 голос
/ 09 июля 2019

Решение, предложенное в посте, на который вы ссылаетесь, подразумевает циклический просмотр диапазона интересов и проверку, равен ли один из элементов диапазона элементу, на котором находится курсор.

Код должен выглядеть следующим образом:

function myFunction() {

  var doc = DocumentApp.getActiveDocument(); 
  var cursor = doc.getCursor();
  var el=cursor.getElement().asText().getText();
  var range;
  //specify the name of the range of interest in getNamedRanges()
  doc.getNamedRanges('testy').forEach(function(rangeEntry){
    (rangeEntry.getRange().getRangeElements().forEach(function(element){
      var child=element.getElement().getText();
      if(child==el){
        Logger.log("Cursor is on named range "+rangeEntry.getName())
      }
    }))
  })
}
...