Mantieni tutto organizzato con le raccolte
Salva e classifica i contenuti in base alle tue preferenze.
L'API Google Docs ti consente di utilizzare gli intervalli denominati per semplificare alcune attività di modifica.
Quando crei un intervallo denominato, identifichi una sezione del documento a cui
puoi fare riferimento in un secondo momento. Gli indici dell'intervallo denominato vengono aggiornati automaticamente man mano che
i contenuti vengono aggiunti e rimossi dal documento. In questo modo, in futuro sarà più semplice individuare il testo da aggiornare, poiché non dovrai tenere traccia delle modifiche di modifica o eseguire ricerche nel documento. In alternativa, puoi ottenere una posizione di modifica leggendo l'intervallo denominato e utilizzando i relativi indici.
Ad esempio, supponiamo di creare un intervallo denominato in cui deve essere visualizzata una stringa "descrizione prodotto" in un documento:
In questo modo puoi sostituire la descrizione: ottieni solo gli indici di inizio e fine dell'intervallo denominato, quindi aggiorna il testo tra questi indici con i nuovi contenuti.
Il seguente codice di esempio mostra come implementare una funzione helper per sostituire i contenuti di un intervallo denominato nel primo foglio del documento, dove l'intervallo denominato è stato creato in precedenza utilizzando CreateNamedRangeRequest.
Per sostituire gli intervalli denominati in tutte le schede, questo codice può essere aumentato per iterare
in tutte le schede. Per ulteriori informazioni ed esempi di codice, consulta la sezione Utilizzare le schede.
Java
/** Replaces the text in existing named ranges. */staticvoidreplaceNamedRange(Docsservice,StringdocumentId,StringrangeName,StringnewText)throwsIOException{// Fetch the document to determine the current indexes of the named ranges.Documentdocument=service.documents().get(documentId).setIncludeTabsContent(true).execute();// Find the matching named ranges in the first tab of the document.NamedRangesnamedRangeList=document.getTabs()[0].getDocumentTab().getNamedRanges().get(rangeName);if(namedRangeList==null){thrownewIllegalArgumentException("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=newArrayList<>();Set<Integer>insertIndexes=newHashSet<>();for(NamedRangenamedRange: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=newArrayList<>();for(Rangerange:allRanges){// Delete all the content in the existing range.requests.add(newRequest().setDeleteContentRange(newDeleteContentRangeRequest().setRange(range)));if(insertIndexes.contains(range.getStartIndex())){// Insert the replacement text.requests.add(newRequest().setInsertText(newInsertTextRequest().setLocation(newLocation().setSegmentId(range.getSegmentId()).setIndex(range.getStartIndex()).setTabId(range.getTabId())).setText(newText)));// Re-create the named range on the new text.requests.add(newRequest().setCreateNamedRange(newCreateNamedRangeRequest().setName(rangeName).setRange(newRange().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.BatchUpdateDocumentRequestbatchUpdateRequest=newBatchUpdateDocumentRequest().setRequests(requests).setWriteControl(newWriteControl().setRequiredRevisionId(document.getRevisionId()));service.documents().batchUpdate(documentId,batchUpdateRequest).execute();}
Python
defreplace_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/workspace/docs/api/concepts/structure#start_and_end_indexnew_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))ifnotnamed_range_list:raiseException('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={}fornamed_rangeinnamed_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=lambdar:r.get('startIndex'),reverse=True)# Create a sequence of requests for each range.requests=[]forrinall_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')ifinsert_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()
Tieni presente che gli intervalli denominati specificano un intervallo di contenuti del documento, ma non fanno parte
di questi contenuti. Se estrai contenuti che includono un intervallo denominato e li inserisci
in un'altra posizione, l'intervallo denominato punta solo ai contenuti originali e non
alla sezione duplicata.
[null,null,["Ultimo aggiornamento 2025-08-29 UTC."],[],[],null,["# Work with named ranges\n\nThe Google Docs API lets you use *named ranges* to simplify some editing tasks.\n\nWhen you create a named range, you identify a section of the document that you\ncan reference later. The indexes of the named range are automatically updated as\ncontent is added to and removed from the document. This simplifies how you\nlocate text for updating in the future, since you don't need to track the\nediting changes or search through the document. Instead, you can get an edit\nlocation by reading the named range and using its indexes.\n\nFor example, suppose you create a named range where a \"product description\"\nstring must appear in a document:\n\nThis lets you replace the description: you just get the start and end indexes of\nthe named range, and then update the text between those indexes with your new\ncontent.\n\nThe following example code shows how you might implement a helper function to\nreplace contents of a named range in the first tab of the document, where the\nnamed range was previously created using the\n[`CreateNamedRangeRequest`](/workspace/docs/api/reference/rest/v1/documents/request#createnamedrangerequest).\nTo replace the named ranges from all tabs, this code can be augmented to iterate\nacross all tabs. See [Work with Tabs](/workspace/docs/api/how-tos/tabs) for more\ninformation and sample code. \n\n### Java\n\n```java\n/** Replaces the text in existing named ranges. */\nstatic void replaceNamedRange(Docs service, String documentId, String rangeName, String newText)\n throws IOException {\n // Fetch the document to determine the current indexes of the named ranges.\n Document document =\n service.documents().get(documentId).setIncludeTabsContent(true).execute();\n\n // Find the matching named ranges in the first tab of the document.\n NamedRanges namedRangeList =\n document.getTabs()[0].getDocumentTab().getNamedRanges().get(rangeName);\n if (namedRangeList == null) {\n throw new IllegalArgumentException(\"The named range is no longer present in the document.\");\n }\n\n // Determine all the ranges of text to be removed, and at which indexes the replacement text\n // should be inserted.\n List\u003cRange\u003e allRanges = new ArrayList\u003c\u003e();\n Set\u003cInteger\u003e insertIndexes = new HashSet\u003c\u003e();\n for (NamedRange namedRange : namedRangeList.getNamedRanges()) {\n allRanges.addAll(namedRange.getRanges());\n insertIndexes.add(namedRange.getRanges().get(0).getStartIndex());\n }\n\n // Sort the list of ranges by startIndex, in descending order.\n allRanges.sort(Comparator.comparing(Range::getStartIndex).reversed());\n\n // Create a sequence of requests for each range.\n List\u003cRequest\u003e requests = new ArrayList\u003c\u003e();\n for (Range range : allRanges) {\n // Delete all the content in the existing range.\n requests.add(\n new Request().setDeleteContentRange(new DeleteContentRangeRequest().setRange(range)));\n\n if (insertIndexes.contains(range.getStartIndex())) {\n // Insert the replacement text.\n requests.add(\n new Request()\n .setInsertText(\n new InsertTextRequest()\n .setLocation(\n new Location()\n .setSegmentId(range.getSegmentId())\n .setIndex(range.getStartIndex())\n .setTabId(range.getTabId()))\n .setText(newText)));\n\n // Re-create the named range on the new text.\n requests.add(\n new Request()\n .setCreateNamedRange(\n new CreateNamedRangeRequest()\n .setName(rangeName)\n .setRange(\n new Range()\n .setSegmentId(range.getSegmentId())\n .setStartIndex(range.getStartIndex())\n .setEndIndex(range.getStartIndex() + newText.length())\n .setTabId(range.getTabId()))));\n }\n }\n\n // Make a batchUpdate request to apply the changes, ensuring the document hasn't changed since\n // we fetched it.\n BatchUpdateDocumentRequest batchUpdateRequest =\n new BatchUpdateDocumentRequest()\n .setRequests(requests)\n .setWriteControl(new WriteControl().setRequiredRevisionId(document.getRevisionId()));\n service.documents().batchUpdate(documentId, batchUpdateRequest).execute();\n}\n```\n\n### Python\n\n```python\ndef replace_named_range(service, document_id, range_name, new_text):\n \"\"\"Replaces the text in existing named ranges.\"\"\"\n\n # Determine the length of the replacement text, as UTF-16 code units.\n # https://developers.google.com/workspace/docs/api/concepts/structure#start_and_end_index\n new_text_len = len(new_text.encode('utf-16-le')) / 2\n\n # Fetch the document to determine the current indexes of the named ranges.\n document = (\n service.documents()\n .get(documentId=document_id, includeTabsContent=True)\n .execute()\n )\n\n # Find the matching named ranges in the first tab of the document.\n named_range_list = (\n document.get('tabs')[0]\n .get('documentTab')\n .get('namedRanges', {})\n .get(range_name)\n )\n if not named_range_list:\n raise Exception('The named range is no longer present in the document.')\n\n # Determine all the ranges of text to be removed, and at which indices the\n # replacement text should be inserted.\n all_ranges = []\n insert_at = {}\n for named_range in named_range_list.get('namedRanges'):\n ranges = named_range.get('ranges')\n all_ranges.extend(ranges)\n # Most named ranges only contain one range of text, but it's possible\n # for it to be split into multiple ranges by user edits in the document.\n # The replacement text should only be inserted at the start of the first\n # range.\n insert_at[ranges[0].get('startIndex')] = True\n\n # Sort the list of ranges by startIndex, in descending order.\n all_ranges.sort(key=lambda r: r.get('startIndex'), reverse=True)\n\n # Create a sequence of requests for each range.\n requests = []\n for r in all_ranges:\n # Delete all the content in the existing range.\n requests.append({\n 'deleteContentRange': {\n 'range': r\n }\n })\n\n segment_id = r.get('segmentId')\n start = r.get('startIndex')\n tab_id = r.get('tabId')\n if insert_at[start]:\n # Insert the replacement text.\n requests.append({\n 'insertText': {\n 'location': {\n 'segmentId': segment_id,\n 'index': start,\n 'tabId': tab_id\n },\n 'text': new_text\n }\n })\n # Re-create the named range on the new text.\n requests.append({\n 'createNamedRange': {\n 'name': range_name,\n 'range': {\n 'segmentId': segment_id,\n 'startIndex': start,\n 'endIndex': start + new_text_len,\n 'tabId': tab_id\n }\n }\n })\n\n # Make a batchUpdate request to apply the changes, ensuring the document\n # hasn't changed since we fetched it.\n body = {\n 'requests': requests,\n 'writeControl': {\n 'requiredRevisionId': document.get('revisionId')\n }\n }\n service.documents().batchUpdate(documentId=document_id, body=body).execute()\n```\n| Named ranges are not private. Anyone using the Docs API to access the document can see the named range definition.\n\nNote that named ranges specify a range of document content, but are not part of\nthat content. If you extract content that includes a named range, then insert it\nat another location, the named range only points to the original content and not\nthe duplicated section."]]