Google เอกสาร API ช่วยให้คุณใช้ช่วงที่มีชื่อเพื่อลดความซับซ้อนของงานแก้ไขบางอย่างได้
เมื่อสร้างช่วงที่มีชื่อ คุณจะระบุส่วนของเอกสารที่จะอ้างอิงได้ในภายหลัง ดัชนีของช่วงที่มีชื่อจะอัปเดตโดยอัตโนมัติเมื่อมีการเพิ่มและนำเนื้อหาออกจากเอกสาร วิธีนี้ช่วยให้คุณค้นหาข้อความเพื่ออัปเดตในอนาคตได้ง่ายขึ้น เนื่องจากคุณไม่จําเป็นต้องติดตามการเปลี่ยนแปลงการแก้ไขหรือค้นหาในเอกสาร แต่คุณรับตำแหน่งการแก้ไขได้โดยการอ่านช่วงที่มีชื่อและใช้ดัชนีของช่วง
ตัวอย่างเช่น สมมติว่าคุณสร้างช่วงที่มีชื่อซึ่งสตริง "รายละเอียดผลิตภัณฑ์" ต้องปรากฏในเอกสาร
ซึ่งจะช่วยให้คุณแทนที่คำอธิบายได้ โดยเพียงแค่ดูดัชนีเริ่มต้นและสิ้นสุดของช่วงที่มีชื่อ แล้วอัปเดตข้อความระหว่างดัชนีเหล่านั้นด้วยเนื้อหาใหม่
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีใช้ฟังก์ชันตัวช่วยเพื่อแทนที่เนื้อหาของช่วงที่มีชื่อในแท็บแรกของเอกสาร ซึ่งก่อนหน้านี้มีการสร้างช่วงที่มีชื่อโดยใช้ CreateNamedRangeRequest
หากต้องการแทนที่ช่วงที่มีชื่อจากทุกแท็บ ให้เพิ่มโค้ดนี้เพื่อวนซ้ำในทุกแท็บ ดูข้อมูลเพิ่มเติมและโค้ดตัวอย่างได้ที่หัวข้อทํางานกับแท็บ
Java
/** 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(); }
Python
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()
โปรดทราบว่าช่วงที่มีชื่อจะระบุช่วงของเนื้อหาเอกสาร แต่ไม่ได้เป็นส่วนหนึ่งของเนื้อหานั้น หากคุณดึงข้อมูลที่มีช่วงที่มีชื่อ แล้วแทรกที่ตำแหน่งอื่น ช่วงที่มีชื่อจะชี้ไปยังเนื้อหาต้นฉบับเท่านั้น โดยไม่ชี้ไปยังส่วนที่ซ้ำกัน