6

NAV 開発環境を必要とせずに、 Dynamics NAV 2013 テーブル メタデータを SQL Server データベースから直接読み取れるようにしたいと考えています。

次のようなクエリを使用して、バイナリ SQL の「イメージ」BLOB 列を表示できます (WHERE 句で適切にフィルター処理します)。

SELECT 
    o.[Name],
    m.[Object Type],
    m.[Metadata], -- XML Metadata
    m.[User Code], -- C# Metadata
    m.[User AL Code] -- C/AL Metadata
FROM [Navision].[dbo].[Object Metadata] AS m
JOIN [Navision].[dbo].[Object] AS o
ON m.[Object ID] = o.[ID]
AND o.[Company Name] = 'YourCompanyName'
AND o.[Type] = 0 -- 0 is NAV Table Object Type

[メタデータ]、[ユーザー コード]、および [ユーザー AL コード] からのバイナリ データを、.Net コードまたは SQL ドライバーを使用したクイック スクリプトを使用してファイルに保存できます。7-zip を使用して解凍し、16 進エディタを使用して表示し、Cygwin の「file」コマンドを使用してこれらの BLOB ファイル タイプを検出しようとしました。

残念ながら、バイナリデータを読み取り可能または使用可能な形式にデコードまたは解凍する方法がわかりません。これらのフィールドのデータを直接使用できるようになるまでは、NAV 開発環境を開き、オブジェクト デザイナーを使用して、ゼロから始まるルックアップ リスト ドロップダウン メニューのコンマ区切りの OptionString プロパティを表示する必要があります (リスト内の各項目は、整数としてのバックエンド データベース - 最初の項目は 0、2 番目の項目は 1 など)。文字列値は SQL ルックアップ テーブルには存在しませんが、NAV はそれらをテーブル メタデータ BLOB に配置します。

これは、NAV 開発者がこれらの番号から名前への NAV カスタム フィールド マッピングを検索する必要なく、DBA として NAV ユーザーを完全にサポートするためのミッシング リンクです。次に、これらのリスト値を検索し、必要に応じて、一致する SQL CASE ステートメントまたはカスタム ルックアップ テーブルを作成できます。

この部分があれば、Dynamics NAV フロントエンド ユーザーまたは開発者ツールにアクセスする必要なく、高度な SQL ビュー、クエリ、レポート、およびツールを作成できるはずです。

これらの NAV オブジェクト メタデータ blob プロパティに使用されるバイナリ データ形式についての知識があれば教えてください。読み取り可能または使用可能な形式に変換する方法についてのアドバイスは役に立ちます。

4

3 に答える 3

5

deV.ch - man vs. code, Dynamics NAV & C# .NET blogの著者から、これらのメタデータ バイナリ フィールドの形式について回答を得ることができました。devch によるリバース エンジニアリングに基づいて、これらのフィールドの最初の 4 バイト (32 ビット) は、カスタム NAV ブロブ タイプを決定する「マジック ナンバー」を格納するために NAV によって使用されることがわかりました。

これらのメタデータ フィールドの場合、NAV Compressed Blob-Type マジック ナンバーは 0x02457d5b (16 進数) です。標準の .Net DeflateStream を使用して圧縮解除するには、最初の 4 つのマジック ナンバー バイトを破棄し、残りのストリームを通常どおり DeflateStream で処理します。

このプロセスは .Net で正常にテストできました。次に、Python または Microsoft 以外の他の deflate ツールを使用してテストし、deflate の実装が業界標準に従っているかどうかを確認する予定です。このソリューションにつながった記事の devch に再度感謝します: Accessing Compressed Blobs from outside NAV (NAV2013) (Revisited)

更新: Python zlib でテストされ、動作します! カスタム NAV Blob タイプのマジック ナンバーが削除されると、標準に準拠した Deflate アルゴリズムが使用されます。サンプルコード (Python) は次のとおりです。

# Example Using Python 3.x
import zlib, sys, struct

# NAV custom Blob-Type identifier (first 4 bytes)
magic = struct.unpack('>I',sys.stdin.buffer.read(4))[0]
print('magic number = %#010x' % magic, file=sys.stderr)
# Remaining binary data is standard DEFLATE without header
input = sys.stdin.buffer.read()
output = zlib.decompress(input,-15)
sys.stdout.buffer.write(output)

次のようなものを使用してテストします。

python -u test.py < Input_Meta.blob > Output_Meta.txt

もちろん、.Net DeflateStream は最初の 4 バイトを削除した後も機能します。この例は、.Net 言語の使用に限定されないことを示すためのものです。

于 2014-01-21T15:55:22.073 に答える
3

Nav を使用してこのテーブルから抽出することは可能でmetadataあり、私が見ることができるように、それはプレーン テキストとして格納されますが、バイナリ フィールドに格納されます。simple を使用してファイルに保存できますMemoryStream(Nav では と呼ばれOutSteramます)。したがって、テーブル番号 3 については、次の XML を取得します。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<MetaTable xmlns="urn:schemas-microsoft-com:dynamics:NAV:MetaObjects" ID="3" CaptionML="ENU=Payment Terms;RUS=Условия платежа" DataPerCompany="1" Name="Payment Terms" LookupFormID="4" DataCaptionFields="1,5">
    <Fields>
        <Field ID="1" Datatype="Code" DataLength="10" Enabled="1" FieldClass="Normal" Name="Code" CaptionML="ENU=Code;RUS=Код" BlankNumbers="DontBlank" BlankZero="0" SignDisplacement="0" Editable="1" NotBlank="1" Numeric="0" DateFormula="0" ClosingDates="0" Title="0" AutoIncrement="0" ValidateTableRelation="1" TestTableRelation="1" ExtendedDatatype="None"/>
        <Field ID="2" Datatype="DateFormula" Enabled="1" FieldClass="Normal" Name="Due Date Calculation" CaptionML="ENU=Due Date Calculation;RUS=Расчет срока оплаты" BlankNumbers="DontBlank" BlankZero="0" SignDisplacement="0" Editable="1" NotBlank="0" Numeric="0" DateFormula="0" ClosingDates="0" Title="0" AutoIncrement="0" ValidateTableRelation="1" TestTableRelation="1" ExtendedDatatype="None"/>
        <Field ID="3" Datatype="DateFormula" Enabled="1" FieldClass="Normal" Name="Discount Date Calculation" CaptionML="ENU=Discount Date Calculation;RUS=Расчет даты скидки" BlankNumbers="DontBlank" BlankZero="0" SignDisplacement="0" Editable="1" NotBlank="0" Numeric="0" DateFormula="0" ClosingDates="0" Title="0" AutoIncrement="0" ValidateTableRelation="1" TestTableRelation="1" ExtendedDatatype="None"/>
        <Field ID="4" Datatype="Decimal" Enabled="1" FieldClass="Normal" Name="Discount %" CaptionML="ENU=Discount %;RUS=Скидка (%)" BlankNumbers="DontBlank" BlankZero="0" SignDisplacement="0" Editable="1" MinValue="0" MaxValue="100" NotBlank="0" Numeric="0" DateFormula="0" ClosingDates="0" Title="0" AutoIncrement="0" ValidateTableRelation="1" TestTableRelation="1" ExtendedDatatype="None"/>
        <Field ID="5" Datatype="Text" DataLength="50" Enabled="1" FieldClass="Normal" Name="Description" CaptionML="ENU=Description;RUS=Описание" BlankNumbers="DontBlank" BlankZero="0" SignDisplacement="0" Editable="1" NotBlank="0" Numeric="0" DateFormula="0" ClosingDates="0" Title="0" AutoIncrement="0" ValidateTableRelation="1" TestTableRelation="1" ExtendedDatatype="None"/>
        <Field ID="6" Datatype="Boolean" Enabled="1" FieldClass="Normal" Name="Calc. Pmt. Disc. on Cr. Memos" CaptionML="ENU=Calc. Pmt. Disc. on Cr. Memos;RUS=Расчет скидки оплаты по кредит-нотам" BlankNumbers="DontBlank" BlankZero="0" SignDisplacement="0" Editable="1" NotBlank="0" Numeric="0" DateFormula="0" ClosingDates="0" Title="0" AutoIncrement="0" ValidateTableRelation="1" TestTableRelation="1" ExtendedDatatype="None"/>
    </Fields>
    <Keys>
        <Key Enabled="1" Key="Field1" MaintainSQLIndex="1" MaintainSIFTIndex="1" Clustered="1"/>
    </Keys>
    <FieldGroups>
        <FieldGroup GroupID="1" GroupName="DropDown" GroupFields="Field1,Field5,Field2"/>
    </FieldGroups>
</MetaTable>

これがあなたが望むものだとしましょう。

Nav のファイルに書き込むコードは次のようになります。

ObjectMetadata:Record(Object Metadata)
Code:BigText
File:File       
CodeStream:InStream     
FileStream:OutStream        

ObjectMetadata.INIT;

IF ObjectMetadata.GET(1,3) THEN
 BEGIN
  ObjectMetadata.CALCFIELDS(Metadata);
  File.CREATE('C:\temp\Code.txt');
  File.CREATEOUTSTREAM(FileStream);

  clear(codestream);
  ObjectMetadata."Metadata".CREATEINSTREAM(CodeStream);
  Code.READ(CodeStream);
  Code.WRITE(FileStream);

  file.close();
 END;

オプションがあります: SQL/.Net で同じことを試してみるか (私はそれに熱心ではありません)、Nav 開発者に定期的に (またはオンデマンドで) すべてのテーブルを処理する何らかのバッチ ジョブを作成するように依頼することができます。 matadata を作成し、それを外部テーブル/ファイル/SQL からアクセスできるものに保存します。

于 2014-01-20T10:08:01.450 に答える
1

Web サービスを使用して、特別なことをしなくても必要なデータを取得してみませんか?

その後、ユーザーは PowerPivot for Excel を使用して、独自のレポートを作成できます。

また、NAV 用の Excel アドインを使用して、NAV から直接 Excel にデータをエクスポートし、Excel 内から更新することもできます。

于 2015-02-10T16:13:45.483 に答える