microtech-graphql
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesemicrotech GraphQL - Skill-Referenz
microtech GraphQL - 技能参考
Kompakte Referenz fuer die GraphQL-Schnittstelle des microtech ERP.
Optimiert fuer Query-Generierung ueber einen MCP-Server mit -Tool.
graphql_queryASCII: Dieses Dokument verwendetstatt Umlaute.ae/oe/ue/ss
WICHTIG - Introspection: NIEMALS das vollstaendige Schema abrufen (). Stattdessen gezielt einzelne Typen abfragen. Siehe__schema.references/introspection-guide.md
Feldkataloge: Fuer detaillierte Feldlisten pro Tabelle siehe.references/feldkatalog-*.md
Erweiterte Themen: Fuer Archiv-Funktionen, externe Bearbeitung, Berechtigungen, Cross-Table-Patterns siehe.references/vorgaenge-erweitert.md
Mutation-Patterns: Fuer Optimistic Locking, rowCopy, ifNotExists, Deep Nesting, Massenoperationen siehe.references/mutation-patterns.md
Query-Patterns: Fuer keyFilter-Details, Arithmetik, skip-Wert, erweitertes @onNull, Schema-Metadaten siehe.references/erweiterte-query-patterns.md
Adressen-Verwaltung: Praxisbeispiele fuer Adressen, Anschriften und Ansprechpartner (lesen, anlegen, aendern, loeschen) mit verschachtelten Links, Optimistic Locking, rowCopy, Massenoperationen und assign-Parametern in. Bei Adress-Aufgaben dort zuerst nachschlagen!references/adressen-verwaltung.md
Parametertabellen: Konfigurations- und Parametertabellen auslesen (Vorgangsarten, Zahlungsbedingungen, Steuerschluessel, Einheiten, Versandarten, Waehrungen, Mahnstufen, Projektstatus u.v.m.) in. Bei Fragen zur mandantenspezifischen Konfiguration dort nachschlagen!references/parametertabellen.md
Workflow-Beispiele: 17 vollstaendige Szenarien (Rechnung erstellen, Vorgang wandeln, Storno, Lagerbestand u.v.m.) in. Bei komplexen Aufgaben dort zuerst nachschlagen!references/workflow-beispiele.md
microtech ERP系统GraphQL接口的简明参考文档。
针对通过MCP服务器使用工具生成查询进行优化。
graphql_queryASCII说明: 本文档使用替代变音字符。ae/oe/ue/ss
重要 - 自省(Introspection): 切勿获取完整Schema(),应针对性地查询单个类型。请参考__schema。references/introspection-guide.md
字段目录: 如需各表的详细字段列表,请查看。references/feldkatalog-*.md
进阶主题: 归档功能、外部编辑、权限、跨表模式等内容,请查看。references/vorgaenge-erweitert.md
变更模式: 乐观锁、rowCopy、ifNotExists、深度嵌套、批量操作等内容,请查看。references/mutation-patterns.md
查询模式: keyFilter详情、算术运算、skip值、扩展@onNull、Schema元数据等内容,请查看。references/erweiterte-query-patterns.md
地址管理: 地址、联系地址和联系人的实操示例(读取、创建、修改、删除),含嵌套链接、乐观锁、rowCopy、批量操作和assign参数,请查看。处理地址相关任务时,请优先查阅此文档!references/adressen-verwaltung.md
参数表: 读取配置和参数表(单据类型、付款条件、税码、单位、配送方式、货币、催款级别、项目状态等),请查看。关于客户端特定配置的问题,请优先查阅此文档!references/parametertabellen.md
工作流示例: 17个完整场景(创建发票、转换单据、冲销、库存查询等),请查看。处理复杂任务时,请优先查阅此文档!references/workflow-beispiele.md
Kritische Regeln (Top 9)
核心规则(Top 9)
- keyFilter-First: Bei JEDEM Filter zuerst pruefen, ob ein passender -Index existiert und
by...verwenden. Erst wenn kein passender Index vorhanden ist, aufkeyFilteroderfastFilterzurueckfallen. Siehe Abschnitt 5 fuer den verbindlichen Workflow.slowFilter - @oneOf-Regel: Pro Filterobjekt nur EIN Operator. Mehrere Bedingungen mit /
andkombinieren.or - /
fnPost/fnReversenur infnConvert-Kontext (nichtrowRead!), immer inrowModify.mutation - vor
rowSave- ohnefnPostsind Positionen nicht gespeichert und werden nicht gebucht.rowSave - Nach nicht mehr schreiben im selben Block - fuehrt zu Laufzeitfehler und Rollback.
rowSave - Leere Belegnummer = Operation fehlgeschlagen - immer in
fldBelegNr-Rueckgaben pruefen.fn... - Prozessketten-Integritaet - NIEMALS fn-Funktionen durch manuelle Operationen ersetzen!
ERP-Prozessfunktionen (,
fnPost,fnReverse,fnConvert) sind die EINZIGE korrekte Art, den Belegstatus zu veraendern. Sie sichern die Prozesskette (z.B. Angebot → AB → Lieferschein → Rechnung), verknuepfen Belege, aktualisieren Lagerbestaende, erzeugen Buchungssaetze und fuehren Plausibilitaetspruefungen durch. Wenn eine fn-Funktion fehlschlaegt, STOPPEN und den Nutzer informieren - KEINEN Workaround versuchen.fnMoveToArchive - NIEMALS als Ersatz fuer
rowNew- ein manuell angelegter Folgebeleg hat KEINE Verknuepfung zum Vorgaenger. Die Prozesskette ist unterbrochen, Mengen werden nicht korrekt gefuehrt, Lieferstatus wird nicht aktualisiert. Stattdessen: Fehlerursache klaeren (Wandlungspfad nicht konfiguriert, Beleg bereits archiviert, etc.) und Nutzer fragen.fnConvert - NIEMALS als Ersatz fuer
rowDelete- eine Loesung perfnReverseumgeht die Storno-Logik: keine Storno-Belegnummer, keine Gegenbuchungen, keine Lagerkorrektur, kein Audit-Trail. Stattdessen:rowDeleteverwenden, bei Fehler Nutzer informieren.fnReverse
- keyFilter优先: 所有过滤操作前,先检查是否存在对应的索引,优先使用
by...。仅当无对应索引时,再使用keyFilter或fastFilter。请查看第5节的强制工作流。slowFilter - @oneOf规则: 每个过滤对象仅允许一个操作符。多条件需用/
and组合。or - /
fnPost/fnReverse仅可在fnConvert上下文使用(不可在rowRead中!),且必须在rowModify内。mutation - 需在
rowSave之前 - 未执行fnPost的话,行项目不会被保存,也无法过账。rowSave - 同一区块内执行后禁止再写入 - 会导致运行时错误和回滚。
rowSave - 空单据编号 = 操作失败 - 务必检查返回结果中的
fn...。fldBelegNr - 流程链完整性 - 切勿用手动操作替代fn函数!
ERP流程函数(、
fnPost、fnReverse、fnConvert)是修改单据状态的唯一正确方式。它们确保流程链的完整性(如报价→订单确认→发货单→发票)、关联单据、更新库存、生成记账凭证并执行合理性检查。若fn函数执行失败,立即停止操作并通知用户 - 切勿尝试替代方案。fnMoveToArchive - 切勿用替代
rowNew- 手动创建的后续单据与原单据无关联,会导致流程链中断、数量统计错误、交付状态无法更新。正确做法:排查失败原因(未配置转换路径、单据已归档等)并询问用户。fnConvert - 切勿用替代
rowDelete- 使用fnReverse删除单据会绕过冲销逻辑:无冲销单据编号、无反向记账、无库存调整、无审计追踪。正确做法:使用rowDelete,若失败则通知用户。fnReverse
Arbeitsweise: So bearbeitest du Nutzeranfragen
工作流程:如何处理用户请求
Schritt 1: Anfrage klassifizieren
步骤1:分类请求
- Lesen/Suchen → (Daten anzeigen, suchen, auflisten, zaehlen)
query - Schreiben/Aendern → (anlegen, aendern, loeschen, buchen, wandeln)
mutation - Unbekannte Felder/Tabelle → Erst Introspection ()
references/introspection-guide.md
Source of Truth: Bei Unsicherheit ueber Feldnamen, Schreibbarkeit oder verfuegbare Operationen IMMER die Live-API per Introspection pruefen. Dokumentierte Feldlisten koennen veraltet sein - die API ist die einzig zuverlaessige Quelle.
- 读取/搜索 → (显示、搜索、列出、统计数据)
query - 写入/修改 → (创建、修改、删除、过账、转换)
mutation - 未知字段/表 → 先执行自省操作()
references/introspection-guide.md
权威来源: 若对字段名称、可写性或可用操作存疑,务必通过自省检查实时API。文档中的字段列表可能过时 - API是唯一可靠的来源。
Schritt 2: Tabelle identifizieren
步骤2:识别表
- Nutze die Tabelle aus "Schnellreferenz" unten
- Bei Unsicherheit: Introspection oder Nutzer fragen
- 使用下方“快速参考”中的表
- 若存疑:执行自省或询问用户
Schritt 3: Reference-Dateien konsultieren
步骤3:查阅参考文档
BEVOR du eine Query oder Mutation baust: Pruefe ob ein passendes Beispiel oder Detail-Wissen existiert.
- Komplexe Aufgabe? → Zuerst durchsuchen (17 Szenarien)
references/workflow-beispiele.md - Feldnamen unklar? → Passenden lesen
references/feldkatalog-*.md - Filter-Logik? → (keyFilter, Arithmetik, Datums-Filter)
references/erweiterte-query-patterns.md - Adressen/Anschriften/Ansprechpartner? → (verschachtelte Links, rowReAnsNr, assign-Parameter, Massenoperationen)
references/adressen-verwaltung.md - Mutation-Pattern? → (Optimistic Locking, rowCopy, Deep Nesting)
references/mutation-patterns.md - Vorgangsfunktionen? → (Archiv, externe Bearbeitung)
references/vorgaenge-erweitert.md - Parametertabellen/Konfiguration? → (Vorgangsarten, Steuerschluessel, Zahlungsbedingungen, Einheiten, Versandarten, Waehrungen, Mahnstufen, Projektstatus, Dokumentenarten u.v.m.)
references/parametertabellen.md - Introspection noetig? → (Typ-Namenskonventionen)
references/introspection-guide.md
Nicht raten - nachschlagen! Die Reference-Dateien enthalten getestete, korrekte Beispiele. Lieber 30 Sekunden lesen als eine fehlerhafte Query bauen.
在构建查询或变更之前: 检查是否存在对应的示例或详细说明。
- 复杂任务? → 先搜索(17个场景)
references/workflow-beispiele.md - 字段名称不明确? → 查阅对应的
references/feldkatalog-*.md - 过滤逻辑? → 查看(keyFilter、算术运算、日期过滤)
references/erweiterte-query-patterns.md - 地址/联系地址/联系人? → 查看(嵌套链接、rowReAnsNr、assign参数、批量操作)
references/adressen-verwaltung.md - 变更模式? → 查看(乐观锁、rowCopy、深度嵌套)
references/mutation-patterns.md - 单据函数? → 查看(归档、外部编辑)
references/vorgaenge-erweitert.md - 参数表/配置? → 查看(单据类型、税码、付款条件、单位、配送方式、货币、催款级别、项目状态、文档类型等)
references/parametertabellen.md - 需要自省? → 查看(类型命名规范)
references/introspection-guide.md
切勿猜测 - 查阅文档! 参考文档包含经过测试的正确示例。与其花时间构建错误的查询,不如花30秒查阅文档。
Schritt 4a: Query bauen (Lesen)
步骤4a:构建查询(读取)
- Filter-Strategie (keyFilter-First!):
- Gibt es einen -Index fuer das Suchfeld? →
by...verwendenkeyFilter - Kein Index? → (einfache Gleichheit auf
fastFilter)fld... - Komplex? → (Arithmetik,
slowFilter,in)fn...
- Gibt es einen
- Query mit -Tool ausfuehren
graphql_query - Ergebnis dem Nutzer verstaendlich praesentieren
- 过滤策略(keyFilter优先!):
- 是否存在针对搜索字段的索引? → 使用
by...keyFilter - 无索引? → 使用(针对
fastFilter字段的简单相等匹配)fld... - 复杂过滤? → 使用(算术运算、
slowFilter、in函数)fn...
- 是否存在针对搜索字段的
- 使用工具执行查询
graphql_query - 向用户清晰展示结果
Schritt 4b: Mutation bauen (Schreiben)
步骤4b:构建变更(写入)
- Operation waehlen:
- Neuer Datensatz → (ggf. mit
rowNew/assignAddress)assignProduct - Aendern →
rowModify - Buchen/Stornieren/Wandeln → +
rowRead/fnPost/fnReversefnConvert - Loeschen → (aber NICHT als Ersatz fuer
rowDelete!)fnReverse
- Neuer Datensatz →
- pruefen: Bei Multi-Tabellen-Mutations immer angeben
@acquireLocks - Speicher-Strategie: vs.
rowSave- bei Vorgaengen mit Positionen immerrowSaveAndModify+ inneresrowSaveAndModifyvorrowSavefnPost - Mutation ausfuehren und Ergebnis pruefen (leere Belegnummer = fehlgeschlagen!)
- 选择操作:
- 新记录 → (可搭配
rowNew/assignAddress)assignProduct - 修改 →
rowModify - 过账/冲销/转换 → +
rowRead/fnPost/fnReversefnConvert - 删除 → (但切勿替代
rowDelete!)fnReverse
- 新记录 →
- 检查: 多表变更时务必指定
@acquireLocks - 保存策略: vs
rowSave- 带行项目的单据务必使用rowSaveAndModify+rowSaveAndModify前执行内部fnPostrowSave - 执行变更并检查结果(空单据编号 = 操作失败!)
Schritt 5: Ergebnis verifizieren
步骤5:验证结果
- Query: Kamen Daten zurueck? Paginierung noetig ()?
hasNextPage - Mutation: pruefen - leer bedeutet die Operation ist fehlgeschlagen
fldBelegNr - Fehler: Abschnitt "Troubleshooting" pruefen, Nutzer informieren
- Nie stillschweigend Fehler ignorieren - immer dem Nutzer mitteilen was passiert ist
- 查询: 是否返回数据?是否需要分页()?
hasNextPage - 变更: 检查- 为空则表示操作失败
fldBelegNr - 错误: 查看“故障排除”部分,通知用户
- 切勿静默忽略错误 - 务必告知用户发生的情况
Typische Nutzer-Szenarien
典型用户场景
| Nutzer sagt... | Du machst... |
|---|---|
| "Zeig mir Artikel X" | |
| "Alle Kunden aus PLZ 5xxxx" | |
| "Erstell eine Rechnung fuer Kunde 10000" | |
| "Wandle Angebot 12345 in AB" | |
| "Wieviele Artikel haben wir?" | |
| "Storniere Rechnung 67890" | |
| "Zeig mir Adresse 10000 mit Anschriften und Ansprechpartnern" | |
| "Leg einen neuen Kunden / Lieferanten / Interesenten an mit Anschrift und Ansprechpartner" | |
| "Welche Vorgangsarten gibt es?" | |
| "Welche Zahlungsbedingungen sind konfiguriert?" | |
| "Zeig mir die Steuerschluessel" | |
| "Welche Einheiten/Waehrungen gibt es?" | |
| 用户需求... | 你需要... |
|---|---|
| "显示商品X" | |
| "所有邮编为5xxxx的客户" | |
| "为客户10000创建一张发票" | 带 |
| "将报价12345转换为订单确认" | |
| "我们有多少种商品?" | |
| "冲销发票67890" | |
| "显示地址10000及其联系地址和联系人" | |
| "创建新客户/供应商/潜在客户,含联系地址和联系人" | |
| "有哪些单据类型?" | |
| "配置了哪些付款条件?" | |
| "显示税码" | |
| "有哪些单位/货币?" | |
Schnellreferenz
快速参考
Wichtigste Tabellen
核心表
| GraphQL-Tabelle | Beschreibung | Schreibbar |
|---|---|---|
| Adressen | ja |
| Anschriften | ja |
| Ansprechpartner | ja |
| Kontakte | ja |
| Artikel | ja |
| Warengruppen | ja |
| Artikel-Lieferanten | ja |
| Vorgaenge | ja |
| Vorgangspositionen | ja (verschachtelt in tblTransactions) |
| Archiv Vorgaenge | ja |
| Projekte | ja |
| Dokumente | ja |
| Kalender | ja |
| Lager | ja |
| Mandant (Einzeldatensatz) | ja |
| Offene Posten | nein |
| Lagerbestaende | nein |
| Benutzer | nein |
| Parametertabellen | ||
| Vorgangsarten (Wandlungskette, Buchungsparameter) | nein |
| Buchungsparameter | nein |
| Mengeneinheiten (UN/ECE-Codes fuer E-Rechnung) | nein |
| Steuerschluessel mit Saetzen und DATEV-Zuordnung | nein |
| Zahlungsbedingungen | nein |
| Fremdwaehrungen mit Wechselkursen | nein |
| Versandarten | nein |
| Adressstatus mit Nummernkreisen | nein |
| Anreden | nein |
| Mahnstufen | nein |
| Zahlungsarten | nein |
| Projektarten | nein |
| Projektstatus (Workflow) | nein |
| Dokumentenarten (DMS) | nein |
| Dokumentenstatus (Workflow) | nein |
| Kommunikationsarten | nein |
| GraphQL表 | 描述 | 可编辑 |
|---|---|---|
| 地址 | 是 |
| 联系地址 | 是 |
| 联系人 | 是 |
| 联系人信息 | 是 |
| 商品 | 是 |
| 商品组 | 是 |
| 商品供应商 | 是 |
| 业务单据 | 是 |
| 单据行项目 | 是(嵌套在tblTransactions中) |
| 归档单据 | 是 |
| 项目 | 是 |
| 文档 | 是 |
| 日历 | 是 |
| 仓库 | 是 |
| 客户端(单条记录) | 是 |
| 未清项 | 否 |
| 库存 | 否 |
| 用户 | 否 |
| 参数表 | ||
| 单据类型(转换链、过账参数) | 否 |
| 过账参数 | 否 |
| 计量单位(电子发票用UN/ECE代码) | 否 |
| 税码(含税率和DATEV映射) | 否 |
| 付款条件 | 否 |
| 外币(含汇率) | 否 |
| 配送方式 | 否 |
| 地址状态(含编号范围) | 否 |
| 称谓 | 否 |
| 催款级别 | 否 |
| 付款方式 | 否 |
| 项目类型 | 否 |
| 项目状态(工作流) | 否 |
| 文档类型(DMS) | 否 |
| 文档状态(工作流) | 否 |
| 通信类型 | 否 |
Haeufigste Patterns (Copy-Paste-fertig)
常用模式(可直接复制使用)
graphql
undefinedgraphql
undefinedLESEN - Einzelner Datensatz
读取 - 单条记录
query { tblProducts { rowRead(kf1ArtNr: { string: "LUTSCHER" }) { fldArtNr fldSuchBeg fldBez1(as: DISPLAY_TEXT) } } }
query { tblProducts { rowRead(kf1ArtNr: { string: "LUTSCHER" }) { fldArtNr fldSuchBeg fldBez1(as: DISPLAY_TEXT) } } }
LESEN - Liste mit Filter
读取 - 带过滤的列表
query { tblProducts { rowsRead(slowFilter: { gt: [{field: fldVk0_Preis}, {value: 0}] }) { fldArtNr fldVk0_Preis(as: TEXT) } } }
query { tblProducts { rowsRead(slowFilter: { gt: [{field: fldVk0_Preis}, {value: 0}] }) { fldArtNr fldVk0_Preis(as: TEXT) } } }
LESEN - Paginiert
读取 - 分页
query ($after: String) { tblProducts { conRead(first: 10, after: $after) { edges { node { fldArtNr } cursor } pageInfo { hasNextPage endCursor } } } }
query ($after: String) { tblProducts { conRead(first: 10, after: $after) { edges { node { fldArtNr } cursor } pageInfo { hasNextPage endCursor } } } }
SCHREIBEN - Neuer Datensatz
写入 - 新记录
mutation { tblProducts { rowNew { fldArtNr(set: { string: "NEU-001" }) fldBez1(set: { text: "Bezeichnung" } as: DISPLAY_TEXT) } } }
mutation { tblProducts { rowNew { fldArtNr(set: { string: "NEU-001" }) fldBez1(set: { text: "新商品" } as: DISPLAY_TEXT) } } }
SCHREIBEN - Datensatz aendern
写入 - 修改记录
mutation { tblProducts { rowModify(kf1ArtNr: { string: "LUTSCHER" }) { fldBez1(set: { text: "Neuer Name" } as: DISPLAY_TEXT) } } }
mutation { tblProducts { rowModify(kf1ArtNr: { string: "LUTSCHER" }) { fldBez1(set: { text: "新名称" } as: DISPLAY_TEXT) } } }
SCHREIBEN - Vorgang anlegen + buchen
写入 - 创建单据并过账
mutation @acquireLocks(forWriting: [tblTransactions, tblTransactionItems], forReading: [tblAddresses, tblProducts]) {
tblTransactions {
rowNew(assignAddress: { kf1AdrNr: { text: "10000" } }) {
fldArt(set: { text: "Rechnung I" })
rowSaveAndModify {
fldBelegNr
tblTransactionItems {
rowNew(assignProduct: { kf1ArtNr: { text: "LUTSCHER" } }) { fldMge(set: { float: 10 }) }
}
rowSave { fnPost { fldBelegNr } } # rowSave VOR fnPost!
}
}
}
}
---mutation @acquireLocks(forWriting: [tblTransactions, tblTransactionItems], forReading: [tblAddresses, tblProducts]) {
tblTransactions {
rowNew(assignAddress: { kf1AdrNr: { text: "10000" } }) {
fldArt(set: { text: "Rechnung I" })
rowSaveAndModify {
fldBelegNr
tblTransactionItems {
rowNew(assignProduct: { kf1ArtNr: { text: "LUTSCHER" } }) { fldMge(set: { float: 10 }) }
}
rowSave { fnPost { fldBelegNr } } # rowSave必须在fnPost之前!
}
}
}
}
---1. Grundstruktur
1. 基础结构
Tabellenzugriff
表访问
Alle Operationen beginnen mit auf oberster Ebene:
tbl...graphql
query {
tblProducts { ... } # Artikel
tblAddresses { ... } # Adressen
tblTransactions { ... } # Vorgaenge
}所有操作均以顶层的开头:
tbl...graphql
query {
tblProducts { ... } # 商品
tblAddresses { ... } # 地址
tblTransactions { ... } # 业务单据
}Leseoperationen
读取操作
| Feld | Beschreibung | Rueckgabe |
|---|---|---|
| Einzelnen Datensatz lesen | |
| Liste lesen | |
| Paginierte Liste (Relay Connection) | |
| 字段 | 描述 | 返回值 |
|---|---|---|
| 读取单条记录 | |
| 读取列表 | |
| 读取分页列表(Relay Connection) | |
Einzeldatensatz-Tabellen
单记录表
tblClientgraphql
query { tblClient { rowRead { fldMandNr fldMandTyp } } }tblClientgraphql
query { tblClient { rowRead { fldMandNr fldMandTyp } } }2. Datensatzauswahl
2. 记录选择
exactMatch
- Exakte Suche
exactMatchexactMatch
- 精确搜索
exactMatchgraphql
rowRead(exactMatch: { byNr: { kf1ArtNr: { string: "PROD-001" } } })graphql
rowRead(exactMatch: { byNr: { kf1ArtNr: { string: "PROD-001" } } })Verschachtelte Schluesselfelder
嵌套关键字段
graphql
rowRead(exactMatch: {
byArtNrLagNr: {
kf1ArtNr: { string: "LUTSCHER"
kf2LagNr: { string: "HAUPT" }
}
}
})graphql
rowRead(exactMatch: {
byArtNrLagNr: {
kf1ArtNr: { string: "LUTSCHER"
kf2LagNr: { string: "HAUPT" }
}
}
})Verkuerzte Schreibweisen
简写方式
graphql
undefinedgraphql
undefinedStatt:
完整写法:
rowRead(exactMatch: { byNr: { kf1ArtNr: { string: "LUTSCHER" } } })
rowRead(exactMatch: { byNr: { kf1ArtNr: { string: "LUTSCHER" } } })
Kurz (impliziert exactMatch + byNr):
简写(隐含exactMatch + byNr):
rowRead(kf1ArtNr: { string: "LUTSCHER" })
rowRead(kf1ArtNr: { string: "LUTSCHER" })
Bereich:
范围查询:
rowsRead(kf1ArtNr: { from: { string: "0" }, to: { string: "12000" } })
undefinedrowsRead(kf1ArtNr: { from: { string: "0" }, to: { string: "12000" } })
undefinedWeitere Sucharten
其他搜索类型
graphql
undefinedgraphql
undefinedNaechster Treffer
最近匹配
rowRead(nearestMatch: { byNr: { kf1ArtNr: { string: "PROD-000" } } })
rowRead(nearestMatch: { byNr: { kf1ArtNr: { string: "PROD-000" } } })
Aktueller Benutzer
当前用户
tblUsers { rowRead(using: current) { fldAnmNa } }
tblUsers { rowRead(using: current) { fldAnmNa } }
Bereich mit exklusiver Obergrenze
带排他上限的范围
rowsRead(allBetween: { byNr: { kf1ArtNr: { from: { string: "A" }, to: { string: "Z" }, toExclusive: true } } })
---rowsRead(allBetween: { byNr: { kf1ArtNr: { from: { string: "A" }, to: { string: "Z" }, toExclusive: true } } })
---3. Datenfelder und Ausgabeformate
3. 数据字段与输出格式
Praefix-System
前缀体系
| Praefix | Bedeutung | Beispiel |
|---|---|---|
| Tabelle | |
| Datenfeld | |
| Schluesselfeld | |
| Sortierfolge | |
| Verweis auf verknuepften Datensatz | |
| Verlinkung zu Datentabelle | |
| Betragsgruppe | |
| Bildfeld | |
| Funktion | |
| System-Feld | |
| 前缀 | 含义 | 示例 |
|---|---|---|
| 表 | |
| 数据字段 | |
| 关键字段 | |
| 排序规则 | |
| 关联记录引用 | |
| 数据表链接 | |
| 金额组 | |
| 图片字段 | |
| 函数 | |
| 系统字段 | |
as
-Parameter - Ausgabeformat
asas
参数 - 输出格式
asgraphql
fldPreis # Standardformat
fldPreis(as: TEXT) # "99,95 EUR" (lokalisiert)
fldPreis(as: FLOAT) # 99.95
fldPreis(as: STRING) # Roher String
fldPreis(as: INT) # Ganzzahl
fldPreis(as: DISPLAY_TEXT) # Anzeigeformat (auch fuer RTF-Felder → Klartext)
fldGueltigAb(as: TEXT) # "24.12.2023" (lokalisiert)
fldGspKz(as: BOOLEAN) # true/falsegraphql
fldPreis # 标准格式
fldPreis(as: TEXT) # "99,95 EUR"(本地化)
fldPreis(as: FLOAT) # 99.95
fldPreis(as: STRING) # 原始字符串
fldPreis(as: INT) # 整数
fldPreis(as: DISPLAY_TEXT) # 显示格式(RTF字段会转换为纯文本)
fldGueltigAb(as: TEXT) # "24.12.2023"(本地化)
fldGspKz(as: BOOLEAN) # true/falseGemeinsame Felder (in fast allen Tabellen)
通用字段(几乎所有表都包含)
undefinedundefinedIdentifikation
标识
fldID # Automatische ID
fldModifyLSN / fldInsertLSN # Versionierung (BigInt)
fldID # 自动ID
fldModifyLSN / fldInsertLSN # 版本号(BigInt)
Audit-Trail
审计追踪
fldErstDat / fldErstBzr # Erstellungsdatum / -benutzer
fldAendDat / fldAendBzr # Aenderungsdatum / -benutzer
fldErstDat / fldErstBzr # 创建日期/创建用户
fldAendDat / fldAendBzr # 修改日期/修改用户
Sperren
锁定
fldGspKz # Gesperrt-Kennzeichen (Boolean)
fldGspDat / fldGspInfo # Sperrdatum / -information
fldGspGrp # Gesperrtgruppe
fldGspKz # 锁定标识(Boolean)
fldGspDat / fldGspInfo # 锁定日期/锁定信息
fldGspGrp # 锁定组
Freitext
自由文本
fldInfo # Informationsfeld
fldMemo # Memo-Feld
fldQuickInfo # QuickInfo
---fldInfo # 信息字段
fldMemo # 备注字段
fldQuickInfo # 快速信息
---4. Verknuepfungen
4. 关联关系
Verweise (row...
) - Einzelner verknuepfter Datensatz
row...引用(row...
)- 单个关联记录
row...graphql
tblProducts {
rowsRead {
fldArtNr
fldWgrNr # Fremdschluessel-Wert
rowWgrNr { fldBez } # Verknuepfte Warengruppe
rowEinh { fldKuBez } # Verknuepfte Einheit
}
}graphql
tblProducts {
rowsRead {
fldArtNr
fldWgrNr # 外键值
rowWgrNr { fldBez } # 关联的商品组
rowEinh { fldKuBez } # 关联的单位
}
}Verlinkungen (lnk...
) - Liste verknuepfter Datensaetze
lnk...链接(lnk...
)- 关联记录列表
lnk...WICHTIG: gehoeren auf INNERHALB des Links, NICHT auf :
by.../using...rowsReadlnk...graphql
undefined重要: 需放在链接内部的上,而非上:
by.../using...rowsReadlnk...graphql
undefinedRICHTIG:
正确写法:
lnkInventory {
rowsRead(byArtNrLagNrArtBDat: { usingArtNr: {} }) { fldLagNr fldMge }
}
lnkInventory {
rowsRead(byArtNrLagNrArtBDat: { usingArtNr: {} }) { fldLagNr fldMge }
}
FALSCH:
错误写法:
lnkInventory(byArtNrLagNrArtBDat: { usingArtNr: {} }) {
rowsRead { ... }
}
undefinedlnkInventory(byArtNrLagNrArtBDat: { usingArtNr: {} }) {
rowsRead { ... }
}
undefinedVerschachtelte Tabellen (tbl...
innerhalb Row)
tbl...嵌套表(Row内的tbl...
)
tbl...graphql
tblClient {
rowRead {
fldMandNr
tblBnkVb { rowsRead { fldNr fldIBAN } }
}
}graphql
tblClient {
rowRead {
fldMandNr
tblBnkVb { rowsRead { fldNr fldIBAN } }
}
}5. Filter
5. 过滤
VERBINDLICHER WORKFLOW: keyFilter-First
强制工作流:keyFilter优先
BEVOR du einen Filter schreibst, fuehre IMMER diese Schritte aus:
-
Sortierfolgen ermitteln: Pruefe per Introspection, welche-Sortierfolgen die Tabelle hat:
by...graphql{ __type(name: "{SingularName}SlowAnyFields") { enumValues { name } } }WICHTIG: Der Enum-Name verwendet den Singular-Namen der Entitaet, NICHT den Tabellennamen! Beispiele:,ProductSlowAnyFields,TransactionSlowAnyFields. Sonderfaelle:AddressSlowAnyFields,CalendarEntrySlowAnyFields,AccountSlowAnyFields,BillOfMaterialsEntrySlowAnyFields. Gleiches Muster gilt fuerInventoryEntrySlowAnyFields. Die{SingularName}FastAnyFields-Parameter findest du auf denby.../rowsRead-Argumenten. Alternativ: ProbiereconReadund schau welche Vorschlaege die API akzeptiert.rowsRead(allBetween: { by -
keyFilter pruefen: Gibt es eine-Sortierfolge, die das gewuenschte Filterfeld als
by...-Schluessel enthaelt? → keyFilter verwenden!kf...graphql# Beispiel: Laender ohne Staatsangehoerigkeitsnummer # byStaatsNr existiert mit kf1StaatsNr → keyFilter nutzen! rowsRead(allBetween: { byStaatsNr: { keyFilter: { isNull: { field: kf1StaatsNr } } } }) -
Fallback: Nur wenn KEIN passender-Index existiert:
by...- fuer einfache Vergleiche auf
fastFilter-Felderfld... - NUR fuer Arithmetik,
slowFilter-Operator,in-Funktionenfn...
NIEMALS direkt verwenden, ohne vorher geprueft zu haben!
slowFilterkeyFilter在编写过滤条件前,务必执行以下步骤:
-
确定排序规则: 通过自省检查表包含哪些排序规则:
by...graphql{ __type(name: "{SingularName}SlowAnyFields") { enumValues { name } } }重要: 枚举名称使用实体的单数名称,而非表名! 示例:,ProductSlowAnyFields,TransactionSlowAnyFields。 特殊情况:AddressSlowAnyFields,CalendarEntrySlowAnyFields,AccountSlowAnyFields,BillOfMaterialsEntrySlowAnyFields。InventoryEntrySlowAnyFields遵循相同模式。{SingularName}FastAnyFields参数可在by.../rowsRead的参数中找到。或者:尝试输入conRead,查看API支持的选项。rowsRead(allBetween: { by -
检查keyFilter: 是否存在包含目标过滤字段作为关键字的
kf...排序规则? → 使用keyFilter!by...graphql# 示例:无税号的国家 # 存在byStaatsNr规则,含kf1StaatsNr → 使用keyFilter! rowsRead(allBetween: { byStaatsNr: { keyFilter: { isNull: { field: kf1StaatsNr } } } }) -
备选方案: 仅当无对应索引时:
by...- 用于
fastFilter字段的简单比较fld... - 仅用于算术运算、
slowFilter操作符、in函数fn...
切勿直接使用slowFilter,务必先检查keyFilter!
Drei Filtertypen
三种过滤类型
| Filter | Performance | Besonderheiten |
|---|---|---|
| Am schnellsten | Filter auf |
| Schnell (DB-seitig) | Nur einfache Vergleiche auf |
| Langsam (App-seitig) | Arithmetik, |
| 过滤类型 | 性能 | 特点 |
|---|---|---|
| 最快 | 对 |
| 快(数据库层面) | 仅支持 |
| 慢(应用层面) | 支持算术运算、 |
Vergleichsoperatoren
比较操作符
graphql
{ eq: [{field: fldStatus}, {value: 1}] } # gleich
{ ne: [{field: fldStatus}, {value: 0}] } # ungleich
{ gt: [{field: fldMge}, {value: 0}] } # groesser
{ lt: [{field: fldMge}, {value: 100}] } # kleiner
{ ge: [{field: fldMge}, {value: 1}] } # groesser-gleich
{ le: [{field: fldMge}, {value: 99}] } # kleiner-gleich
{ isNull: { field: fldAuftrNr } } # NULL-Pruefung
{ isNotNull: { field: fldAuftrNr } }graphql
{ eq: [{field: fldStatus}, {value: 1}] } # 等于
{ ne: [{field: fldStatus}, {value: 0}] } # 不等于
{ gt: [{field: fldMge}, {value: 0}] } # 大于
{ lt: [{field: fldMge}, {value: 100}] } # 小于
{ ge: [{field: fldMge}, {value: 1}] } # 大于等于
{ le: [{field: fldMge}, {value: 99}] } # 小于等于
{ isNull: { field: fldAuftrNr } } # 检查NULL
{ isNotNull: { field: fldAuftrNr } }Boolesche Kombinationen
布尔组合
graphql
{ and: [Ausdruck1, Ausdruck2] }
{ or: [Ausdruck1, Ausdruck2] }
{ not: Ausdruck }graphql
{ and: [表达式1, 表达式2] }
{ or: [表达式1, 表达式2] }
{ not: 表达式 }WICHTIG: @oneOf-Regel
重要:@oneOf规则
Pro Filterobjekt nur EIN Operator:
graphql
undefined每个过滤对象仅允许一个操作符:
graphql
undefinedFALSCH:
错误写法:
fastFilter: { eq: [...], gt: [...] }
fastFilter: { eq: [...], gt: [...] }
RICHTIG:
正确写法:
fastFilter: { and: [ { eq: [...] }, { gt: [...] } ] }
undefinedfastFilter: { and: [ { eq: [...] }, { gt: [...] } ] }
undefinedIN-Operator (nur slowFilter)
IN操作符(仅slowFilter支持)
graphql
{ in: { left: { field: fldLagBestArt }, list: [1, 7] } }Alle Werte muessen denselben Typ haben (@sametype-Regel).
graphql
{ in: { left: { field: fldLagBestArt }, list: [1, 7] } }所有值必须为同一类型(@sametype规则)。
keyFilter - Performantester Filter
keyFilter - 性能最优的过滤
Filtert auf -Felder INNERHALB des -Parameters. Schneller als fast/slowFilter.
kf...by...graphql
undefined对参数内的字段过滤,比fast/slowFilter更快。
by...kf...graphql
undefinedAlle Artikel ab Nummer "10"
所有编号从"10"开始的商品
rowsRead(
allBetween: {
byNr: {
keyFilter: { ge: [{ field: kf1ArtNr }, { value: "10" }] }
kf1ArtNr: { from: { string: "0" }, to: { string: "ZZZZZ" } }
}
}
)
rowsRead(
allBetween: {
byNr: {
keyFilter: { ge: [{ field: kf1ArtNr }, { value: "10" }] }
kf1ArtNr: { from: { string: "0" }, to: { string: "ZZZZZ" } }
}
}
)
Mehrere Werte per OR
多值OR查询
keyFilter: {
or: [
{ eq: [{ field: kf1AdrNr }, { value: "10000" }] }
{ eq: [{ field: kf1AdrNr }, { value: "70000" }] }
]
}
**Prioritaet:** `keyFilter` > `fastFilter` > `slowFilter` (immer schnellsten moegl. Typ waehlen).
Detaillierte keyFilter-Patterns siehe `references/erweiterte-query-patterns.md`.keyFilter: {
or: [
{ eq: [{ field: kf1AdrNr }, { value: "10000" }] }
{ eq: [{ field: kf1AdrNr }, { value: "70000" }] }
]
}
**优先级:** `keyFilter` > `fastFilter` > `slowFilter`(始终选择最快的可用类型)。
详细keyFilter模式请查看`references/erweiterte-query-patterns.md`。Funktionen in Filtern (nur slowFilter)
过滤中的函数(仅slowFilter支持)
graphql
{ fnPos: [{ value: "Suchtext" }, { field: fldSuchBeg }] } # Textsuche (>0 = gefunden, NUR String-Felder!)
{ fnGetAktDate: [] } # Aktuelles Datum
{ fnIncDate: [{ fnGetAktDate: [] }, { value: 0 }, { value: -12 }] } # Datum +/- Monategraphql
{ fnPos: [{ value: "搜索文本" }, { field: fldSuchBeg }] } # 文本搜索(>0表示找到,仅支持字符串字段!)
{ fnGetAktDate: [] } # 当前日期
{ fnIncDate: [{ fnGetAktDate: [] }, { value: 0 }, { value: -12 }] } # 日期加减月份Arithmetik in slowFilter
slowFilter中的算术运算
graphql
undefinedgraphql
undefinedBrutto > 100 pruefen
检查总价>100
slowFilter: { gt: [{ mul: [{ field: fldVk0_Preis }, { value: 1.19 }] }, { value: 100 }] }
Operatoren: `add`, `sub`, `mul`, `div`, `mod`, `neg`. Details in `references/erweiterte-query-patterns.md`.
---slowFilter: { gt: [{ mul: [{ field: fldVk0_Preis }, { value: 1.19 }] }, { value: 100 }] }
操作符:`add`, `sub`, `mul`, `div`, `mod`, `neg`。详情请查看`references/erweiterte-query-patterns.md`。
---6. Direktiven
6. 指令
@store
- Wert in Variable speichern
@store@store
- 将值存入变量
@storeVariable muss in der Operations-Signatur deklariert werden:
graphql
query ($storedValue: Any = null) {
tblProducts {
rowsRead {
fldSuchBeg @store(in: $storedValue)
echo: _any(value: $storedValue)
}
}
}@store变量需在操作签名中声明:
graphql
query ($storedValue: Any = null) {
tblProducts {
rowsRead {
fldSuchBeg @store(in: $storedValue)
echo: _any(value: $storedValue)
}
}
}@store@onNull
- Null-Behandlung
@onNull@onNull
- NULL处理
@onNullgraphql
fldSuchBeg @onNull(returnValue: "Nicht gefunden") # Alternativwert
fldPreis @onNull(returnValue: skip) # Feld ueberspringen
fldArtNr @onNull(errorMessage: "ArtNr fehlt") # Fehler ausloesengraphql
fldSuchBeg @onNull(returnValue: "未找到") # 替代值
fldPreis @onNull(returnValue: skip) # 跳过字段
fldArtNr @onNull(errorMessage: "商品编号缺失") # 触发错误@acquireLocks
- Praventive Sperren (nur mutation)
@acquireLocks@acquireLocks
- 预防性锁定(仅mutation支持)
@acquireLocksgraphql
mutation @acquireLocks(
forWriting: [tblTransactions, tblTransactionItems],
forReading: [tblAddresses, tblProducts]
) { ... }Verhindert Deadlocks bei Multi-Tabellen-Mutationen.
graphql
mutation @acquireLocks(
forWriting: [tblTransactions, tblTransactionItems],
forReading: [tblAddresses, tblProducts]
) { ... }避免多表变更时的死锁。
@skip
/ @include
@skip@include@skip
/ @include
@skip@includegraphql
fldPreis @include(if: $includePrice)graphql
fldPreis @include(if: $includePrice)7. System-Felder
7. 系统字段
graphql
undefinedgraphql
undefinedWertausgabe
值输出
_any(value: $variable)
_string(expr: { add: [{field: fldArtNr}, {value: " - "}, {field: fldSuchBeg}] })
_boolean(expr: { gt: [{field: fldLagMge}, {value: 0}] })
_localDate(expr: { fnGetAktDate: [] })
_any(value: $variable)
_string(expr: { add: [{field: fldArtNr}, {value: " - "}, {field: fldSuchBeg}] })
_boolean(expr: { gt: [{field: fldLagMge}, {value: 0}] })
_localDate(expr: { fnGetAktDate: [] })
Bedingte Ausfuehrung
条件执行
details: _if(expr: { gt: [{field: fldLagMge}, {value: 0}] }) {
fldStdPreis
fldLagMge
}
details: _if(expr: { gt: [{field: fldLagMge}, {value: 0}] }) {
fldStdPreis
fldLagMge
}
Bedingter Skalarwert
条件标量值
status: _ifThenElse(
expr: { gt: [{field: fldLagMge}, {value: 0}] },
then: "Verfuegbar",
else: "Nicht auf Lager"
)
status: _ifThenElse(
expr: { gt: [{field: fldLagMge}, {value: 0}] },
then: "有库存",
else: "无库存"
)
Fehler ausloesen
触发错误
_raise(message: "Negative Lagermenge!")
---_raise(message: "库存数量为负!")
---8. Mutationen
8. 变更操作
query vs. mutation
query vs mutation
- : Snapshot-Transaktion, keine Sperren, null bei Fehler
query - : Normale Transaktion, Alles-oder-Nichts (Fehler = Rollback)
mutation
- :快照事务,无锁定,错误时返回null
query - :常规事务,全有或全无(错误则回滚)
mutation
Schreiboperationen
写入操作
| Operation | Zweck |
|---|---|
| Neuen Datensatz erstellen |
| Nur erstellen wenn nicht vorhanden (gibt |
| Datensatz kopieren (nicht-gesetzte Felder vom Original) |
| Datensatz aendern |
| Datensatz loeschen |
| Massenoperationen (Fehler bei einem → Rollback aller) |
| 操作 | 用途 |
|---|---|
| 创建新记录 |
| 仅当记录不存在时创建(返回 |
| 复制记录(未设置的字段继承原记录值) |
| 修改记录 |
| 删除记录 |
| 批量操作(一条记录失败则所有操作回滚) |
Row-Kontexte
Row上下文
| Kontext | Schreiben | | |
|---|---|---|---|
| ja | nein | ja |
| nein | ja (mit Schreiben) | nein |
| nein | nein | nein |
| 上下文 | 可写入 | | |
|---|---|---|---|
| 是 | 否 | 是 |
| 否 | 是(可写入) | 否 |
| 否 | 否 | 否 |
Datensatz erstellen
创建记录
graphql
mutation {
tblProducts {
rowNew {
fldArtNr(set: { string: "PROD-001" })
fldBez1(set: { text: "Neuer Artikel" } as: DISPLAY_TEXT)
fldVk0_Preis(set: { float: 99.95 })
} # Automatisch gespeichert am Block-Ende
}
}Bedingt (kein Fehler wenn vorhanden, gibt zurueck):
nullgraphql
rowNew(ifNotExists: { exactMatch: { byNr: { kf1ArtNr: { string: "PROD-001" } } } })graphql
mutation {
tblProducts {
rowNew {
fldArtNr(set: { string: "PROD-001" })
fldBez1(set: { text: "新商品" } as: DISPLAY_TEXT)
fldVk0_Preis(set: { float: 99.95 })
} # 块结束时自动保存
}
}条件创建(记录已存在时无错误,返回):
nullgraphql
rowNew(ifNotExists: { exactMatch: { byNr: { kf1ArtNr: { string: "PROD-001" } } } })Datensatz kopieren
复制记录
graphql
mutation {
tblProducts {
rowCopy(kf1ArtNr: { string: "LUTSCHER" }) {
fldArtNr(set: { string: "LUTSCHER-V2" })
# Alle anderen Felder (Preis, Bez., etc.) vom Original uebernommen
fldBez1(as: DISPLAY_TEXT)
fldVk0_Preis(as: FLOAT)
}
}
}Details zu rowCopy, ifNotExists und Optimistic Locking in .
references/mutation-patterns.mdgraphql
mutation {
tblProducts {
rowCopy(kf1ArtNr: { string: "LUTSCHER" }) {
fldArtNr(set: { string: "LUTSCHER-V2" })
# 其他字段(价格、名称等)继承原记录值
fldBez1(as: DISPLAY_TEXT)
fldVk0_Preis(as: FLOAT)
}
}
}rowCopy、ifNotExists和乐观锁的详情请查看。
references/mutation-patterns.mdDatensatz aendern
修改记录
graphql
mutation {
tblProducts {
rowModify(kf1ArtNr: { string: "PROD-001" }) {
fldVk0_Preis(set: { float: 129.95 })
fldBez1(as: DISPLAY_TEXT) # Nur lesen
}
}
}graphql
mutation {
tblProducts {
rowModify(kf1ArtNr: { string: "PROD-001" }) {
fldVk0_Preis(set: { float: 129.95 })
fldBez1(as: DISPLAY_TEXT) # 仅读取
}
}
}Datensatz loeschen
删除记录
graphql
mutation {
tblProducts {
rowDelete(kf1ArtNr: { string: "PROD-001" }, ignoreWarnings: true) {
fldArtNr # Noch lesbar vor Loeschung
}
}
}graphql
mutation {
tblProducts {
rowDelete(kf1ArtNr: { string: "PROD-001" }, ignoreWarnings: true) {
fldArtNr # 删除前仍可读取
}
}
}Speicheroperationen
保存操作
graphql
undefinedgraphql
undefinedrowSave - Speichern, dann Read-Kontext (lnk... verfuegbar)
rowSave - 保存后进入Read上下文(lnk...可用)
rowNew {
fldArtNr(set: { string: "X" })
rowSave { fldID fldModifyLSN } # Ab hier nur lesen + lnk...
}
rowNew {
fldArtNr(set: { string: "X" })
rowSave { fldID fldModifyLSN } # 从此处开始仅可读取 + 使用lnk...
}
rowSaveAndModify - Speichern, weiter schreiben
rowSaveAndModify - 保存后可继续写入
rowNew {
fldArtNr(set: { string: "X" })
rowSaveAndModify {
fldBez1(set: { text: "Name" } as: DISPLAY_TEXT)
tblTransactionItems { ... } # Verschachtelte Tabelle schreibbar
}
}
**WICHTIG:** Nach `rowSave`/`rowSaveAndModify` NICHT mehr im aeusseren Block schreiben!rowNew {
fldArtNr(set: { string: "X" })
rowSaveAndModify {
fldBez1(set: { text: "名称" } as: DISPLAY_TEXT)
tblTransactionItems { ... } # 嵌套表可编辑
}
}
**重要:** 执行`rowSave`/`rowSaveAndModify`后,切勿在外层块中继续写入!Feldmanipulation (set
-Parameter)
set字段操作(set
参数)
setgraphql
fldArtNr(set: { string: "PROD-005" }) # String
fldVk0_Preis(set: { float: 99.95 }) # Float
fldVk0_Preis(set: { text: "99,95" }) # Lokalisierter Text
fldGspAbDat(set: { text: "2023-12-24" }) # Datum (ISO-Format YYYY-MM-DD, auch localdate moeglich)
fldGspKz(set: { boolean: true }) # Boolean
fldArt(set: { text: "Rechnung I" }) # Vorgangsart (immer Text, Nummern koennen abweichen!)
fldMge(set: { int: 5 }) # Integer
fldGspAbDat(set: {}) # NULL setzengraphql
fldArtNr(set: { string: "PROD-005" }) # 字符串
fldVk0_Preis(set: { float: 99.95 }) # 浮点数
fldVk0_Preis(set: { text: "99,95" }) # 本地化文本
fldGspAbDat(set: { text: "2023-12-24" }) # 日期(ISO格式YYYY-MM-DD,也支持localdate)
fldGspKz(set: { boolean: true }) # 布尔值
fldArt(set: { text: "Rechnung I" }) # 单据类型(始终使用文本,编号可能因配置不同而变化!)
fldMge(set: { int: 5 }) # 整数
fldGspAbDat(set: {}) # 设置为NULLAuto-Nummerierung (naechste freie Nr wenn vergeben)
自动编号(保存时分配下一个可用编号)
fldAdrNr(set: { text: "10000", allowAutoNrOnSave: true })
fldAdrNr(set: { text: "10000", allowAutoNrOnSave: true })
Kaskadierende Updates unterdruecken
抑制级联更新
fldZahlBed(set: { text: "30 Tage netto", suppressRelatedUpdates: true })
undefinedfldZahlBed(set: { text: "30天净付", suppressRelatedUpdates: true })
undefinedAssign-Parameter
Assign参数
graphql
undefinedgraphql
undefinedRow-Assign: Felder aus anderem Datensatz befuellen
Row-Assign:从其他记录填充字段
rowNew(assignAddress: { kf1AdrNr: { text: "10000" } }) { ... }
rowNew(assignUser: { using: current }) { ... }
rowNew(assignAddress: { kf1AdrNr: { text: "10000" } }) { ... }
rowNew(assignUser: { using: current }) { ... }
Feld-Assign: Einzelnes Feld per Suche zuweisen
Feld-Assign:通过搜索分配单个字段
fldWgrNr(assignProductGroup: { exactMatch: { byBez: { kf1Bez: { text: "Elektronik" } } } })
fldSBzrNr(assignUser: { using: current })
fldWgrNr(assignProductGroup: { exactMatch: { byBez: { kf1Bez: { text: "电子" } } } })
fldSBzrNr(assignUser: { using: current })
using: context in Verlinkungen (nimmt aeusseren Datensatz)
using: 链接中的上下文(使用外层记录)
lnkProjects { rowNew(assignAddress: { using: context }) { ... } }
undefinedlnkProjects { rowNew(assignAddress: { using: context }) { ... } }
undefinedVerlinkungen in Mutationen (nur in RowMutationRead)
变更中的链接(仅RowMutationRead支持)
graphql
mutation {
tblAddresses {
rowRead(kf1AdrNr: { string: "10000" }) {
lnkPostalAddresses {
rowNew(setAdrNrAnsNr: usingAdrNr) {
fldNa2(set: { text: "Lieferanschrift" })
rowSave { fldAnsNr }
}
}
}
}
}set...rowNewgraphql
mutation {
tblAddresses {
rowRead(kf1AdrNr: { string: "10000" }) {
lnkPostalAddresses {
rowNew(setAdrNrAnsNr: usingAdrNr) {
fldNa2(set: { text: "送货地址" })
rowSave { fldAnsNr }
}
}
}
}
}链接中的参数:自动从上下文中填充关键字段。
rowNewset...9. Vorgaenge - Kern-Workflow
9. 业务单据 - 核心工作流
Vorgangsarten
单据类型
WICHTIG: Immer statt verwenden - Nummern koennen pro Installation abweichen!
textintgraphql
fldArt(set: { text: "Rechnung I" }) # RICHTIG - Bezeichnung
fldArt(set: { int: 70 }) # VERMEIDEN - Nummer kann abweichenHinweis: akzeptiert den Parameter sowohl als Integer als auch als Text:
fnConverttransactionTypeNographql
fnConvert(transactionTypeNo: 50, ...) # Integer - Standard-Nummer (50 = Lieferschein)
fnConvert(transactionTypeNo: "Lieferschein", ...) # Text - BezeichnungStandard-Nummern und Bezeichnungen finden sich in .
references/vorgangsarten.mdVollstaendige Liste aller Vorgangsarten mit Standard-Nummern und Buchungsparametern:
references/vorgangsarten.md重要: 始终使用而非 - 编号可能因安装配置不同而变化!
textintgraphql
fldArt(set: { text: "Rechnung I" }) # 正确写法 - 使用名称
fldArt(set: { int: 70 }) # 避免使用 - 编号可能不同注意: 接受参数,支持整数和文本:
fnConverttransactionTypeNographql
fnConvert(transactionTypeNo: 50, ...) # 整数 - 标准编号(50=发货单)
fnConvert(transactionTypeNo: "Lieferschein", ...) # 文本 - 名称标准编号和名称请查看。
references/vorgangsarten.md所有单据类型的完整列表(含标准编号和过账参数):
references/vorgangsarten.mdFunktionsuebersicht
函数概述
| Funktion | Beschreibung | Kontext | Rueckgabe |
|---|---|---|---|
| Buchen | | Einzelwert |
| Stornieren | | Einzelwert |
| Wandeln | | Array |
| Archivieren | | Einzelwert |
Alle erfordern: + -Kontext. Leere Belegnummer = fehlgeschlagen.
mutationrowRead| 函数 | 描述 | 上下文 | 返回值 |
|---|---|---|---|
| 过账 | | 单个值 |
| 冲销 | | 单个值 |
| 转换 | | 数组 |
| 归档 | | 单个值 |
所有函数要求: + 上下文。空单据编号 = 操作失败。
mutationrowReadVorgang anlegen mit Positionen
创建带行项目的单据
graphql
mutation @acquireLocks(
forWriting: [tblTransactions, tblTransactionItems]
forReading: [tblAddresses, tblProducts]
) {
tblTransactions {
rowNew(assignAddress: { kf1AdrNr: { text: "10000" } }) {
fldArt(set: { text: "Rechnung I" })
rowSaveAndModify {
fldBelegNr
tblTransactionItems {
pos1: rowNew(assignProduct: { kf1ArtNr: { text: "LUTSCHER" } }) {
fldMge(set: { float: 10 })
}
pos2: rowNew(assignProduct: { kf1ArtNr: { text: "MYSTERYBOX" } }) {
fldMge(set: { float: 2 })
}
}
}
}
}
}Hinweise:
- akzeptiert Artikelnummern UND Barcodes (Auto-Resolve)
fldArtNr - kann als Nummer (
fldArt) oder Text (int: 50) gesetzt werdentext: "Rechnung I" - fuegt Position an den Anfang
fldZeilenNr(set: { int: 0 })
graphql
mutation @acquireLocks(
forWriting: [tblTransactions, tblTransactionItems]
forReading: [tblAddresses, tblProducts]
) {
tblTransactions {
rowNew(assignAddress: { kf1AdrNr: { text: "10000" } }) {
fldArt(set: { text: "Rechnung I" })
rowSaveAndModify {
fldBelegNr
tblTransactionItems {
pos1: rowNew(assignProduct: { kf1ArtNr: { text: "LUTSCHER" } }) {
fldMge(set: { float: 10 })
}
pos2: rowNew(assignProduct: { kf1ArtNr: { text: "MYSTERYBOX" } }) {
fldMge(set: { float: 2 })
}
}
}
}
}
}注意:
- 接受商品编号和条形码(自动解析)
fldArtNr - 可设置为编号(
fldArt)或文本(int: 50)text: "Rechnung I" - 将行项目添加到开头
fldZeilenNr(set: { int: 0 })
Vorgang buchen (fnPost
)
fnPost过账单据(fnPost
)
fnPostgraphql
undefinedgraphql
undefinedBestehenden Vorgang buchen
过账已有单据
mutation {
tblTransactions {
rowRead(exactMatch: { byBelegNr: { kf1BelegNr: { string: "RE12500005" } } }) {
fnPost { fldBelegNr } # Leer = nicht gebucht!
}
}
}
undefinedmutation {
tblTransactions {
rowRead(exactMatch: { byBelegNr: { kf1BelegNr: { string: "RE12500005" } } }) {
fnPost { fldBelegNr } # 空值表示未过账!
}
}
}
undefinedAnlegen + Buchen in einer Mutation
单次变更中创建并过账单据
graphql
mutation @acquireLocks(
forWriting: [tblTransactions, tblTransactionItems]
forReading: [tblAddresses, tblProducts]
) {
tblTransactions {
rowNew(assignAddress: { kf1AdrNr: { text: "10000" } }) {
fldArt(set: { text: "Rechnung I" })
rowSaveAndModify {
fldBelegNr
tblTransactionItems {
pos1: rowNew(assignProduct: { kf1ArtNr: { text: "LUTSCHER" } }) {
fldMge(set: { float: 10 })
}
}
rowSave { # WICHTIG: Erst speichern!
fnPost { fldBelegNr } # Dann buchen
}
}
}
}
}graphql
mutation @acquireLocks(
forWriting: [tblTransactions, tblTransactionItems]
forReading: [tblAddresses, tblProducts]
) {
tblTransactions {
rowNew(assignAddress: { kf1AdrNr: { text: "10000" } }) {
fldArt(set: { text: "Rechnung I" })
rowSaveAndModify {
fldBelegNr
tblTransactionItems {
pos1: rowNew(assignProduct: { kf1ArtNr: { text: "LUTSCHER" } }) {
fldMge(set: { float: 10 })
}
}
rowSave { # 重要:先保存!
fnPost { fldBelegNr } # 再过账
}
}
}
}
}Vorgang stornieren (fnReverse
)
fnReverse冲销单据(fnReverse
)
fnReversegraphql
mutation {
tblTransactions {
rowRead(exactMatch: { byBelegNr: { kf1BelegNr: { string: "RE12500002" } } }) {
fnReverse { fldBelegNr }
}
}
}graphql
mutation {
tblTransactions {
rowRead(exactMatch: { byBelegNr: { kf1BelegNr: { string: "RE12500002" } } }) {
fnReverse { fldBelegNr }
}
}
}Vorgang wandeln (fnConvert
)
fnConvert转换单据(fnConvert
)
fnConvertGibt ein Array zurueck (kann mehrere Vorgaenge erzeugen):
graphql
mutation {
tblTransactions {
rowRead(exactMatch: { byBelegNr: { kf1BelegNr: { string: "AN2500001" } } }) {
fnConvert(transactionTypeNo: 50, deliveryQuantityHandling: IGNORE) {
fldBelegNr
}
}
}
}deliveryQuantityHandlingIGNOREKEEP_UNCHANGEDRECALCULATERECALCULATE_IF_ZERO返回数组(可能生成多个单据):
graphql
mutation {
tblTransactions {
rowRead(exactMatch: { byBelegNr: { kf1BelegNr: { string: "AN2500001" } } }) {
fnConvert(transactionTypeNo: 50, deliveryQuantityHandling: IGNORE) {
fldBelegNr
}
}
}
}deliveryQuantityHandlingIGNOREKEEP_UNCHANGEDRECALCULATERECALCULATE_IF_ZEROPreisberechnung nach Speichern
保存后的价格计算
graphql
rowSave {
acoGPreis {
totalGrossAmount # Brutto
totalNetAmount # Netto
totalTaxAmount # Steuer
}
}graphql
rowSave {
acoGPreis {
totalGrossAmount # 总价(含税)
totalNetAmount # 净价
totalTaxAmount # 税额
}
}10. Betragsgruppen (aco...
)
aco...10. 金额组(aco...
)
aco...Kurzbeispiel Lesen:
acoEPr { totalGrossAmount totalNetAmount totalTaxAmount }Details (Lesen, Schreiben, Preisberechnung nach Speichern):
references/betragsgruppen.md读取示例:
acoEPr { totalGrossAmount totalNetAmount totalTaxAmount }详情(读取、写入、保存后价格计算):
references/betragsgruppen.md11. Paginierung (Relay Connection)
11. 分页(Relay Connection)
graphql
query ($pageSize: Int = 10, $after: String) {
tblProducts {
conRead(first: $pageSize, after: $after) {
edges {
cursor
node { fldArtNr fldSuchBeg }
}
pageInfo { hasNextPage endCursor startCursor edgeCount }
}
}
}WICHTIG: gibt nur die Anzahl der zurueckgegebenen Edges zurueck, NICHT die Gesamtanzahl der Datensaetze. Es gibt kein -Feld. Zum Zaehlen: mit ausreichend grossem Wert setzen und pruefen.
edgeCounttotalCountfirsthasNextPagegraphql
query ($pageSize: Int = 10, $after: String) {
tblProducts {
conRead(first: $pageSize, after: $after) {
edges {
cursor
node { fldArtNr fldSuchBeg }
}
pageInfo { hasNextPage endCursor startCursor edgeCount }
}
}
}重要: 仅返回当前返回的Edges数量,而非总记录数。无字段。如需统计:设置足够大的值并检查。
edgeCounttotalCountfirsthasNextPage12. Haeufige Fehler vermeiden
12. 常见错误规避
| Fehler | Loesung |
|---|---|
| Nur in |
| Immer |
Schreiben nach | Nach |
| Erst |
| Mehrere Operatoren in einem Filterobjekt | |
| Getrennte Mutationen (Auto-Archivierung!) |
| Leere Belegnummer nicht geprueft | Immer |
| Gehoeren auf |
| Korrekt: |
| Fehlende Berechtigung - |
| Feldreihenfolge nicht beachtet | Felder werden sequentiell ausgefuehrt - Menge VOR Preis setzen |
| Kopie braucht eigenen Primaerschluessel |
| Ein Fehler bei einem Datensatz → Rollback ALLER Loeschungen |
| VERBOTEN! Bricht die Prozesskette. Fehlerursache klaeren und Nutzer informieren |
| VERBOTEN! Umgeht Storno-Logik (keine Gegenbuchungen, kein Audit-Trail). Nutzer informieren |
| VERBOTEN! Folgeschritte (z.B. Wandlung) setzen erfolgreiche Buchung voraus. Nutzer informieren |
| VERBOTEN! Archivierung hat eigene Logik. Nutzer informieren |
| Prozessschritte ueberspringen (z.B. direkt RE statt AB→LI→RE) | Nur wenn Nutzer dies explizit bestaetigt. Auf moeglichen Kettenverlust hinweisen |
| |
| Diese Felder leben in |
| 错误 | 解决方案 |
|---|---|
| 仅在 |
未执行 | 始终在 |
同一区块内 | |
写入上下文中使用 | 先执行 |
| 单个过滤对象中使用多个操作符 | 使用 |
单次变更中 | 拆分为独立变更(自动归档!) |
| 未检查空单据编号 | 始终检查 |
| 应放在链接内部的 |
使用 | 正确写法: |
出现 | 无权限 - 无此字段的写入权限 |
| 未注意字段顺序 | 字段按顺序执行 - 先设置数量再设置价格 |
| 副本需有独立主键 |
| 一条记录失败则所有删除操作回滚 |
| 禁止! 会中断流程链。排查失败原因并通知用户 |
| 禁止! 绕过冲销逻辑(无反向记账、无审计追踪)。通知用户 |
| 禁止! 后续步骤(如转换)依赖成功过账。通知用户 |
| 禁止! 归档有专属逻辑。通知用户 |
| 跳过流程步骤(如直接创建发票而非订单确认→发货单→发票) | 仅当用户明确确认时执行,需告知用户可能的流程中断风险 |
将 | |
在 | 这些字段属于 |
13. Troubleshooting
13. 故障排除
Fehlermeldung: "Argument \"set\" is not defined"
"Argument \"set\" is not defined"错误信息:"Argument \"set\" is not defined"
"Argument \"set\" is not defined"Ursache: Fehlende Berechtigung. Der API-Nutzer hat kein Recht, dieses Feld zu setzen.
Loesung: Berechtigung im ERP pruefen. Berechtigungs-pflichtige Felder: , , , , , .
fldDatfldVerkfldKredLimitfldInExtBeaKzfldGspKzfldEPreis原因: 权限不足。API用户无此字段的写入权限。
解决方案: 在ERP中检查权限。需权限的字段:, , , , , 。
fldDatfldVerkfldKredLimitfldInExtBeaKzfldGspKzfldEPreisFehlermeldung: "Address \"10002\" is blocked."
"Address \"10002\" is blocked."错误信息:"Address \"10002\" is blocked."
"Address \"10002\" is blocked."Ursache: Adresse hat (Gesperrt-Kennzeichen).
Loesung: Andere Adresse verwenden oder Sperrung im ERP aufheben.
fldGspKz = true原因: 地址的(锁定标识)。
解决方案: 使用其他地址或在ERP中解除锁定。
fldGspKz = trueLeere Belegnummer nach fnPost
/fnReverse
/fnConvert
fnPostfnReversefnConvertfnPost
/fnReverse
/fnConvert
后返回空单据编号
fnPostfnReversefnConvertUrsache: Funktion konnte nicht ausgefuehrt werden (Voraussetzungen nicht erfuellt).
Loesung: Immer Belegnummer pruefen: . Leer = fehlgeschlagen.
fnPost { fldBelegNr }原因: 函数执行失败(未满足前置条件)。
解决方案: 始终检查单据编号:。空值表示执行失败。
fnPost { fldBelegNr }Rollback nach fnPost
trotz erfolgreicher Buchung
fnPostfnPost
成功过账后仍回滚
fnPostUrsache: Eine NACHFOLGENDE Operation in derselben Mutation ist fehlgeschlagen. Alles-oder-Nichts.
Loesung: und Folgeoperationen in getrennte Mutationen aufteilen, oder Fehlerquelle beheben.
fnPost原因: 同一次变更中的后续操作失败,触发全量回滚。
解决方案: 将与后续操作拆分为独立变更,或修复错误源。
fnPostfnPost
hat keine Wirkung (Positionen fehlen)
fnPostfnPost
无效果(行项目缺失)
fnPostUrsache: vor vergessen. arbeitet nur auf gespeicherten Daten.
Loesung: Immer - VOR .
rowSavefnPostfnPostrowSave { fnPost { fldBelegNr } }rowSavefnPost原因: 调用前未执行。仅处理已保存的数据。
解决方案: 始终使用 - 必须在之前。
fnPostrowSavefnPostrowSave { fnPost { fldBelegNr } }rowSavefnPostlnk...
-Felder nicht verfuegbar
lnk...lnk...
字段不可用
lnk...Ursache: Datensatz ist noch in schreibendem Kontext ().
Loesung: Erst aufrufen → wechselt zu → wird verfuegbar.
RowMutationNew/Copy/ModifyrowSaveRowMutationReadlnk...原因: 记录仍处于写入上下文()。
解决方案: 先调用 → 切换到上下文 → 可用。
RowMutationNew/Copy/ModifyrowSaveRowMutationReadlnk...Laufzeitfehler nach rowSave
rowSaverowSave
后出现运行时错误
rowSaveUrsache: Versuch im selben Block nach noch Felder zu schreiben.
Loesung: verwenden wenn danach noch geschrieben werden soll, oder alle Schreiboperationen VOR platzieren.
rowSaverowSaveAndModifyrowSave原因: 同一区块内后尝试写入字段。
解决方案: 如需继续写入,使用,或所有写入操作放在之前。
rowSaverowSaveAndModifyrowSaveDeadlock bei parallelen Mutationen
并行变更时出现死锁
Ursache: fehlt oder unvollstaendig.
Loesung: mit ALLEN beteiligten Tabellen.
@acquireLocks@acquireLocks(forWriting: [...], forReading: [...])原因: 缺少或不完整的。
解决方案: 使用指定所有涉及的表。
@acquireLocks@acquireLocks(forWriting: [...], forReading: [...])fn-Funktion schlaegt fehl (fnConvert/fnPost/fnReverse/fnMoveToArchive)
fn函数执行失败(fnConvert/fnPost/fnReverse/fnMoveToArchive)
Ursache: Vielfaeltig - fehlende Konfiguration (Wandlungspfad), Beleg bereits archiviert, fehlende Berechtigung, Geschaeftsregel verletzt, Beleg gesperrt.
Loesung: STOPP - KEINEN Workaround versuchen! Insbesondere:
- NICHT per einen Ersatzbeleg anlegen (bricht Prozesskette)
rowNew - NICHT per einen Beleg loeschen statt zu stornieren (umgeht Audit-Trail)
rowDelete - NICHT den naechsten Prozessschritt ausfuehren wenn der aktuelle fehlschlug Stattdessen: Fehlermeldung dem Nutzer zeigen und gemeinsam klaeren. Moegliche Ursachen:
- Wandlungspfad im ERP nicht konfiguriert → ERP-Administrator muss Pfad freischalten
- Beleg bereits im Archiv → nur auf aktive Vorgaenge moeglich
fnConvert - Fehlende Berechtigung → API-Nutzer-Rechte pruefen
- Geschaeftsregel verletzt → Beleg-Daten pruefen (z.B. fehlende Pflichtfelder)
原因: 多种可能 - 未配置转换路径、单据已归档、权限不足、违反业务规则、单据被锁定。
解决方案: 停止操作 - 切勿尝试替代方案!尤其是:
- 禁止用创建替代单据(会中断流程链)
rowNew - 禁止用删除单据替代冲销(绕过审计追踪)
rowDelete - 禁止在当前步骤失败后执行后续流程 正确做法:向用户展示错误信息并共同排查原因。可能的原因:
- ERP中未配置转换路径 → 需ERP管理员启用路径
- 单据已归档 → 仅支持活跃单据
fnConvert - 权限不足 → 检查API用户权限
- 违反业务规则 → 检查单据数据(如必填字段缺失)
Query gibt null
zurueck obwohl Datensatz existiert
null—
Ursache (in mutation): stimmt nicht ueberein (Optimistic Locking Konflikt).
Ursache (in query): Schluessel falsch oder Sortierfolge stimmt nicht.
Loesung: -Pattern verwenden um Konflikte abzufangen. Siehe .
modifyLSN@onNullreferences/mutation-patterns.md—