با محدوده های نامگذاری شده کار کنید، با محدوده های نامگذاری شده کار کنید

Google Docs API به شما امکان می دهد از محدوده های نامگذاری شده برای ساده کردن برخی از کارهای ویرایش استفاده کنید.

وقتی محدوده ای با نام ایجاد می کنید، بخشی از سند را شناسایی می کنید که می توانید بعداً به آن ارجاع دهید. با اضافه شدن و حذف محتوا به سند، فهرست‌های محدوده نام‌گذاری شده به‌طور خودکار به‌روزرسانی می‌شوند. این روش مکان یابی متن را برای به روز رسانی در آینده ساده می کند، زیرا نیازی به ردیابی تغییرات ویرایش یا جستجو در سند ندارید. در عوض، می‌توانید با خواندن محدوده نام‌گذاری شده و استفاده از فهرست‌های آن، یک مکان ویرایش دریافت کنید.

به عنوان مثال، فرض کنید یک محدوده با نام ایجاد می کنید که در آن رشته «شرح محصول» باید در یک سند ظاهر شود:

این به شما امکان می دهد توضیحات را جایگزین کنید: شما فقط نمایه های شروع و پایان محدوده نامگذاری شده را دریافت می کنید و سپس متن بین این فهرست ها را با محتوای جدید خود به روز می کنید.

کد مثال زیر نشان می دهد که چگونه می توانید یک تابع کمکی را برای جایگزینی محتویات یک محدوده نامگذاری شده در برگه اول سند پیاده سازی کنید، جایی که محدوده نامگذاری شده قبلاً با استفاده از CreateNamedRangeRequest ایجاد شده است. برای جایگزینی محدوده‌های نام‌گذاری‌شده از همه برگه‌ها، این کد را می‌توان برای تکرار در همه برگه‌ها تقویت کرد. برای اطلاعات بیشتر و نمونه کد، به Work with Tabs مراجعه کنید.

جاوا

/** Replaces the text in existing named ranges. */
static void replaceNamedRange(Docs service, String documentId, String rangeName, String newText)
    throws IOException {
  // Fetch the document to determine the current indexes of the named ranges.
  Document document =
      service.documents().get(documentId).setIncludeTabsContent(true).execute();

  // Find the matching named ranges in the first tab of the document.
  NamedRanges namedRangeList =
      document.getTabs()[0].getDocumentTab().getNamedRanges().get(rangeName);
  if (namedRangeList == null) {
    throw new IllegalArgumentException("The named range is no longer present in the document.");
  }

  // Determine all the ranges of text to be removed, and at which indexes the replacement text
  // should be inserted.
  List<Range> allRanges = new ArrayList<>();
  Set<Integer> insertIndexes = new HashSet<>();
  for (NamedRange namedRange : namedRangeList.getNamedRanges()) {
    allRanges.addAll(namedRange.getRanges());
    insertIndexes.add(namedRange.getRanges().get(0).getStartIndex());
  }

  // Sort the list of ranges by startIndex, in descending order.
  allRanges.sort(Comparator.comparing(Range::getStartIndex).reversed());

  // Create a sequence of requests for each range.
  List<Request> requests = new ArrayList<>();
  for (Range range : allRanges) {
    // Delete all the content in the existing range.
    requests.add(
        new Request().setDeleteContentRange(new DeleteContentRangeRequest().setRange(range)));

    if (insertIndexes.contains(range.getStartIndex())) {
      // Insert the replacement text.
      requests.add(
          new Request()
              .setInsertText(
                  new InsertTextRequest()
                      .setLocation(
                          new Location()
                              .setSegmentId(range.getSegmentId())
                              .setIndex(range.getStartIndex())
                              .setTabId(range.getTabId()))
                      .setText(newText)));

      // Re-create the named range on the new text.
      requests.add(
          new Request()
              .setCreateNamedRange(
                  new CreateNamedRangeRequest()
                      .setName(rangeName)
                      .setRange(
                          new Range()
                              .setSegmentId(range.getSegmentId())
                              .setStartIndex(range.getStartIndex())
                              .setEndIndex(range.getStartIndex() + newText.length())
                              .setTabId(range.getTabId()))));
    }
  }

  // Make a batchUpdate request to apply the changes, ensuring the document hasn't changed since
  // we fetched it.
  BatchUpdateDocumentRequest batchUpdateRequest =
      new BatchUpdateDocumentRequest()
          .setRequests(requests)
          .setWriteControl(new WriteControl().setRequiredRevisionId(document.getRevisionId()));
  service.documents().batchUpdate(documentId, batchUpdateRequest).execute();
}

پایتون

def replace_named_range(service, document_id, range_name, new_text):
    """Replaces the text in existing named ranges."""

    # Determine the length of the replacement text, as UTF-16 code units.
    # https://developers.google.com/docs/api/concepts/structure#start_and_end_index
    new_text_len = len(new_text.encode('utf-16-le')) / 2

    # Fetch the document to determine the current indexes of the named ranges.
    document = (
        service.documents()
        .get(documentId=document_id, includeTabsContent=True)
        .execute()
    )

    # Find the matching named ranges in the first tab of the document.
    named_range_list = (
        document.get('tabs')[0]
        .get('documentTab')
        .get('namedRanges', {})
        .get(range_name)
    )
    if not named_range_list:
        raise Exception('The named range is no longer present in the document.')

    # Determine all the ranges of text to be removed, and at which indices the
    # replacement text should be inserted.
    all_ranges = []
    insert_at = {}
    for named_range in named_range_list.get('namedRanges'):
        ranges = named_range.get('ranges')
        all_ranges.extend(ranges)
        # Most named ranges only contain one range of text, but it's possible
        # for it to be split into multiple ranges by user edits in the document.
        # The replacement text should only be inserted at the start of the first
        # range.
        insert_at[ranges[0].get('startIndex')] = True

    # Sort the list of ranges by startIndex, in descending order.
    all_ranges.sort(key=lambda r: r.get('startIndex'), reverse=True)

    # Create a sequence of requests for each range.
    requests = []
    for r in all_ranges:
        # Delete all the content in the existing range.
        requests.append({
            'deleteContentRange': {
                'range': r
            }
        })

        segment_id = r.get('segmentId')
        start = r.get('startIndex')
        tab_id = r.get('tabId')
        if insert_at[start]:
            # Insert the replacement text.
            requests.append({
                'insertText': {
                    'location': {
                        'segmentId': segment_id,
                        'index': start,
                        'tabId': tab_id
                    },
                    'text': new_text
                }
            })
            # Re-create the named range on the new text.
            requests.append({
                'createNamedRange': {
                    'name': range_name,
                    'range': {
                        'segmentId': segment_id,
                        'startIndex': start,
                        'endIndex': start + new_text_len,
                        'tabId': tab_id
                    }
                }
            })

    # Make a batchUpdate request to apply the changes, ensuring the document
    # hasn't changed since we fetched it.
    body = {
        'requests': requests,
        'writeControl': {
            'requiredRevisionId': document.get('revisionId')
        }
    }
    service.documents().batchUpdate(documentId=document_id, body=body).execute()

توجه داشته باشید که محدوده های نامگذاری شده محدوده ای از محتوای سند را مشخص می کنند، اما بخشی از آن محتوا نیستند. اگر محتوایی را استخراج می‌کنید که شامل یک محدوده نام‌گذاری شده است، سپس آن را در مکان دیگری درج می‌کنید، محدوده نام‌گذاری‌شده فقط به محتوای اصلی اشاره می‌کند و نه بخش تکراری.