0

私はWindows 7でJMP 9.0.3 64ビットを使用しており、Pythonから自動化しています(編集:VBScript自動化でバグが同様に再現でき、JMP 11.0.0にまだ存在することを確認しました)。私の自動化コードはJMP 9 Automation Guideに基づいています。すべての JMP9 PDF は Web サイトから消えたようです

このバグは、私にとってかなりのショーストッパーになりつつあります。自動化コードでテーブルを操作し、テーブル名を JSL コードと交換する必要が頻繁に発生しますが、このバグにより、これを確実に行うことができなくなります。他の誰かがそれに遭遇しましたか?既知の修正または回避策はありますか?

(私は StackOverflow で JMP/JSL に関する質問をあまり見たことがありませんが、たまたま JMP を使用している潜伏者がいる可能性があるので、ここに投稿しています。最初は SAS の JMP フォーラムに投稿されました: https://community.jmp.com /メッセージ/213132#213132 )

問題

Document自動化オブジェクトには、関連付けられた JMP テーブルのテーブル名またはファイル名を反映するプロパティ、、および がありNameますFullNamePathただし、多くの場合、JSL コードからアクセスできる空白でない名前がテーブルにあり、実際にはこの名前を使用してテーブル自動化オブジェクトを取得できるにもかかわらず、これらのプロパティは空白になります。

デモコード

バグを示す Python コードを次に示します。JSL を使用してテーブルを作成し、このテーブルの名前を保存して、テーブルのオートメーション オブジェクトを名前で検索します。次に、 がテーブルの既知の名前に一致するかどうかをチェックtable.Document.Nameし (検索に使用されたものです!)、一致しない場合を報告します。これを 100 回実行し、通常、最初の 2 ~ 4 回の繰り返しの後、名前が空白に戻り始めます。

from win32com.client import gencache
mod = gencache.GetModuleForProgID("JMP.Application")
app = mod.Application()

okay_table = [None]*100

for ii in range(len(okay_table)):
    # Create a table in JMP
    app.RunCommand("show(%d); ::dt=New Table(); ::retval=dt<<Get Name()" % ii)

    # Retrieve the name of that just-created table from the JSL variable
    retval = app.GetJSLValue("retval")

    # Retrieve the automation object for that table, by name
    table = app.GetTableHandleFromName(retval)

    # Now, table.Document.Name **SHOULD** match retval, but
    # it may be blank due to the bug.

    if not any((table.Document.Name, table.Document.Path, table.Document.FullName)):
        print "table %d: got blank table.Document.Name=%s, Path=%s, FullName=%s" % (ii,
            table.Document.Name, table.Document.Path, table.Document.FullName)
        app.RunCommand("close(DataTable(::retval), nosave)")
        okay_table[ii]=False
    else:
        print "table %d: looks okay; Name=%s, FullName=%s, Path=%s" % (ii,
            table.Document.Name, table.Document.FullName, table.Document.Path)
        app.RunCommand('close(DataTable("%s"), nosave)' % table.Document.Name)
        okay_table[ii]=True

print "Number of bad tables: %d" % okay_table.count(False)

典型的な出力:

table 0: looks okay; Name=Untitled 304, FullName=Untitled 304.jmp, Path=Untitled 304.jmp
table 1: looks okay; Name=Untitled 305, FullName=Untitled 305.jmp, Path=Untitled 305.jmp
table 2: got blank table.Document.Name=, Path=, FullName=
table 3: got blank table.Document.Name=, Path=, FullName=
table 4: got blank table.Document.Name=, Path=, FullName=
...
table 98: got blank table.Document.Name=, Path=, FullName=
table 99: got blank table.Document.Name=, Path=, FullName=
Number of bad tables: 98
4

1 に答える 1

0

私は回避策を思いつきましたが、それは耐え難いほど厄介なものです。自動化テーブルの名前を取得するために、次のようにします。

  1. JSL コードを実行して、リスト内のすべての JMP テーブルの名前を取得します。
  2. app.GetJSLValueこのリストを自動化アプリケーションに取得するために使用します。
  3. 名前のリストを 1 つずつループし、自動化テーブル オブジェクトを名前で検索します。app.GetTableHandleFromName
  4. 次に、醜いクラッジを使用して、各テーブルの OLE オブジェクト ID をターゲット テーブルの OLE オブジェクト ID と比較します。一致する場合は、検索に使用した名前を返します。

私の恐ろしい醜い回避策のコード:

def GetTableName(app, table):
    if table.Document.Name:
        return table.Document.Name
    else:
        # Get names of all JMP tables
        app.RunCommand("""
            NamesDefaultToHere(1);
            ::_retval={};
            for(ii=1, ii<=NTable(), ii++,
                InsertInto(::_retval, DataTable(ii)<<GetName())
            )""")
        tns = app.GetJSLValue("_retval")

        # See this thread for why == works here (http://thread.gmane.org/gmane.comp.python.windows/12977/focus=12978)
        for tn in tns:
            if table == self.app.GetTableHandleFromName(tn)
                return tn
        else:
            raise Exception
于 2014-09-29T16:31:49.853 に答える