> For the complete documentation index, see [llms.txt](https://docs.geodin.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.geodin.com/geodin-ground/workflows-and-integrations/arcgis-integration/arcgis-pro-attach-reports.md).

# Attaching reports to borehole annotations

{% embed url="<https://www.youtube.com/watch?v=34Gydh4vkws>" %}

> **Video chapters:** 0:00 How GeoDin organizes borehole report folders | 0:37 Finding document annotations | 1:14 Preparing the AttachKey field | 1:53 Selecting boreholes with linked documents | 2:25 Calculating the AttachKey values | 3:33 Enabling & generating attachment matches | 4:35 Adding the attachments | 5:34 Verifying the attached reports

When a Civil 3D drawing with GeoDin® Ground boreholes is brought into ArcGIS Pro ([previous tutorial](/geodin-ground/workflows-and-integrations/arcgis-integration/arcgis-pro-ground-model.md)), the exported PDF reports can be attached to each borehole's document annotation - so the right geotechnical report opens from the right feature. This tutorial builds a matching key and runs the two geoprocessing tools that wire the PDFs to the annotations.

{% hint style="info" %}
For the same workflow starting from GeoDin®-exported point layers (one record per borehole), see [Attach reports](https://docs.geodin.com/integrations-and-plug-ins/overview/attach-reports) in the GeoDin® documentation. The version below handles the Civil 3D annotation layer, where each borehole has **multiple** annotation records.
{% endhint %}

## Step 1: Locate the reports and confirm the annotations

* On import, GeoDin® Ground creates a documents folder next to the drawing, structured by project with one subfolder per borehole, each holding that borehole's geotechnical report.
* Copy the report PDFs into one working folder to simplify matching.

<figure><img src="/files/O8tJctdpnGEX92hKJtaN" alt=""><figcaption><p>The exported documents folder and a borehole's Geotech Soil Log PDF</p></figcaption></figure>

* In the annotation layer's attribute table, confirm the borehole's document record: its **RefName** reads "1 document(s)".

<figure><img src="/files/oi8MGA6Znyjbiix8Iyai" alt=""><figcaption><p>The document annotation record in the attribute table</p></figcaption></figure>

## Step 2: Add a key field

* Open the feature class fields view and add a new field named **AttachKey** with **Data Type = Text**. Save the changes.

<figure><img src="/files/QO0F2kftmini2P8o9zXm" alt=""><figcaption><p>The AttachKey field added as Text</p></figcaption></figure>

## Step 3: Select only the document annotations

* Use **Select By Attributes** with the clause: **RefName contains the text** `document`.
* Apply and verify the selection count before continuing - the key must only be calculated for these records.

<figure><img src="/files/MELg6Gb7r1MrprAc0rgu" alt=""><figcaption><p>Selecting the document annotation records</p></figcaption></figure>

## Step 4: Calculate the key

* With the selection active, right-click **AttachKey > Calculate Field**, set **Expression Type = Python**, expression `extract_bh(!Layer!)`, and this code block:

```python
def extract_bh(layer):
    layer = layer.upper()

    # Define known prefix and suffix
    prefix = "LOC_BASE-"
    suffix = "-BASIC"

    if layer.startswith(prefix) and layer.endswith(suffix):
        return layer[len(prefix):-len(suffix)] + " -"

    return None
```

<figure><img src="/files/nHtK40LDB28cYoqa4Uq0" alt=""><figcaption><p>Calculate Field applied to the selected records only</p></figcaption></figure>

* The trailing `" -"` is intentional: it makes the key specific enough to prefix-match exactly one report filename, so similarly named boreholes (BH1 vs. BH1A) cannot cross-match.

<figure><img src="/files/v0Q0ZecdP4299B0ZTCZe" alt=""><figcaption><p>The populated key - borehole name plus trailing dash</p></figcaption></figure>

## Step 5: Enable attachments

* Open the feature class **Properties > Manage** and enable **Attachments** (attachments are a geodatabase feature - the annotation layer must be a geodatabase feature class, not a shapefile). Save.

<figure><img src="/files/PmVc0kwGMLXebcl9IYsm" alt=""><figcaption><p>Attachments enabled on the feature class</p></figcaption></figure>

## Step 6: Generate the match table

* Run the **Generate Attachment Match Table** geoprocessing tool:
  * **Input Dataset**: the annotation layer (selected records).
  * **Input Folder**: the working folder with the PDFs.
  * **Key Field**: `AttachKey` - **Input Data Filter**: `*.pdf` - **Match Pattern**: **Prefix**.

<figure><img src="/files/I68lQiF9L9BdY8rQfsTj" alt=""><figcaption><p>Generate Attachment Match Table with Match Pattern set to Prefix</p></figcaption></figure>

## Step 7: Add the attachments

* Run **Add Attachments** with the same input dataset, **Input Join Field** `OBJECTID`, the match table from step 6, and **Match Join Field** `MatchID`.

<figure><img src="/files/MhyXicEGXfWXu5GgfCTB" alt=""><figcaption><p>Add Attachments joining OBJECTID to MatchID</p></figcaption></figure>

## Step 8: Verify

* Click a document annotation in the scene and scroll its pop-up: the geotechnical report appears as an attachment.
* Spot-check one or two more boreholes to confirm the matching worked consistently.

<figure><img src="/files/9MoEEeST0X7hmIoSPE1T" alt=""><figcaption><p>The report attached to the annotation, verified in the pop-up</p></figcaption></figure>

## Optional settings

* **Selection scope** - calculate the key **only for the selected document records**; calculating across all rows creates incorrect matches.
* **Key specificity** - if several reports have similar names, make the key format more specific before matching (the trailing `" -"` exists for exactly this).

***

## Working with attachment matching

Confirm attachments are enabled before running the match and add tools, and spot-check one borehole after each stage (key calculated, match table generated, attachments added) so a mismatch is caught one step from its cause rather than at the end.

***

**Next step:** [Publish and review the model as a web scene](/geodin-ground/workflows-and-integrations/arcgis-integration/arcgis-web-scene.md) - the attached reports stay available in the published scene's pop-ups.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.geodin.com/geodin-ground/workflows-and-integrations/arcgis-integration/arcgis-pro-attach-reports.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
