Skip to main content
Inspiring
February 20, 2024
Answered

ExtendScriptでサイズの多い文書ファイル内に存在する要素を順に参照すると、FrameMakerが強制終了する。

  • February 20, 2024
  • 2 replies
  • 196 views

FrameMaker2015,2019で本現象は確認しております。

サイズの多い(6.5MB程)構造化文書データが存在するbookファイルで、下記のExtendScriptを実行した場合に、FrameMakerがエラーなしで強制終了してしまいます。

データに起因するものなのかの判断は出来ておりません。

/**********************************************************************
Menu
***********************************************************************/
var newMenu = DefineMenu("TestMenu", "Test");
var elementIdCmd     = DefineCommand(1, "elementCommand", "Element", "");
newMenu.AddCommandToMenu(elementIdCmd);
fmMenu = app.GetNamedMenu("!MakerMainMenu");

if(fmMenu.ObjectValid())
{
    fmMenu.AddMenuToMenu(newMenu);
}

fmMenu = app.GetNamedMenu("!BookMainMenu");
if(fmMenu.ObjectValid())
{
    fmMenu.AddMenuToMenu(newMenu);
}

UpdateMenus();

/**********************************************************************
command execution 
***********************************************************************/
function Command(cmd){
    switch(cmd)
    {
        case 1:
        {
            ElementInBook();

            break;
        }
        default:
        {
            break;
        }
    }
}


/**********************************************************************
Process
***********************************************************************/
function ElementInBook()
{
	var bookId = app.ActiveBook;

	if(bookId.ObjectValid()) {
		openAllFilesInBook(bookId, false);

                var bookCompId = bookId.FirstComponentInBook;
		while(bookCompId.ObjectValid()) {
			var docPathName = bookCompId.Name;
			var docFileName = getFileNameFromPath(docPathName);
			var docId = getOpenDocId(docPathName);

			if(docId.ObjectValid()) {
				var flowId = docId.MainFlowInDoc;
				var elemId = flowId.HighestLevelElement;

				while(elemId.ObjectValid()) {
					elemId = elemId.NextElementDFS;
				}
			}

			bookCompId = bookCompId.NextComponentInBook;
		}

		saveAndCloseAllFilesInBook(bookId, false);
	}
}


function getFileNameFromPath(filePath)
{
    var filename = filePath.match(/([^\\]*)\./)[1];
    var extend = filePath.match(/[^.]+$/);

    var filename_ex = filename + "." + extend;

    return filename_ex;
}


function openFileIgnoreError(docPathName, view)
{
    var docId, i;

    var openProps = GetOpenDefaultParams();
    var retParm = new PropVals();

    i = GetPropIndex(openProps, Constants.FS_FileIsInUse);
    openProps[i].propVal.ival = Constants.FV_ResetLockAndContinue;

    i = GetPropIndex(openProps, Constants.FS_FontChangedMetric);
    openProps[i].propVal.ival = Constants.FV_DoOK;

    i = GetPropIndex(openProps, Constants.FS_FontNotFoundInCatalog);
    openProps[i].propVal.ival = Constants.FV_DoOK;

    i = GetPropIndex(openProps, Constants.FS_FontNotFoundInDoc);
    openProps[i].propVal.ival = Constants.FV_DoOK;

    i = GetPropIndex(openProps, Constants.FS_LanguageNotAvailable);
    openProps[i].propVal.ival = Constants.FV_DoOK;

    i = GetPropIndex(openProps, Constants.FS_RefFileNotFound);
    openProps[i].propVal.ival = Constants.FV_AllowAllRefFilesUnFindable;

    i = GetPropIndex(openProps, Constants.FS_UseAutoSaveFile);
    openProps[i].propVal.ival = Constants.FV_DoNo;

    i = GetPropIndex(openProps, Constants.FS_UseRecoverFile);
    openProps[i].propVal.ival = Constants.FV_DoNo;

    i = GetPropIndex(openProps, Constants.FS_MakeVisible);
    openProps[i].propVal.ival = view;

    docId = Open(docPathName, openProps, retParm);

    return docId;
}


function getOpenDocId(docPathName)
{
    var docId = app.FirstOpenDoc;
    while(docId) {
        var pathName = docId.Name;
        if(pathName === docPathName) break;

        docId = docId.NextOpenDocInSession;
    }

    return docId;
}


function openAllFilesInBook(bookId, makeVisible)
{
    var bookCompId = bookId.FirstComponentInBook;
    while(bookCompId.ObjectValid()) {
        var docPathName = bookCompId.Name;
        var docId = openFileIgnoreError(docPathName, makeVisible);

        bookCompId = bookCompId.NextComponentInBook;
    }
}


function saveAndCloseAllFilesInBook(bookId, flag)
{
    var bookCompId = bookId.FirstComponentInBook;
    while(bookCompId.ObjectValid()) {
        var docPathName = bookCompId.Name;
        var docId = getOpenDocId(docPathName);

        if(docId.ObjectValid()) {
            if(flag) docId.SimpleSave(docPathName, flag);
            docId.Close(Constants.FF_CLOSE_MODIFIED);
        }

        bookCompId = bookCompId.NextComponentInBook;
    }
}

 

FrameMakerが強制終了せずに、全部の要素を参照していく方法をご教示いただけますでしょうか。

八方塞がりで、どうしたものかと困っています。

 

どうぞよろしくお願いいたします。

This topic has been closed for replies.
Correct answer s-onishi

NextElementDFSプロパティを使用する方法をやめて、TextItemのFTI_ElementBeginを使用する方法に変更すると、問題なく動作していました。

 

取得出来る要素の数が10倍程NextElementDFSの方が多いという差が発生しておりました。

要素内のテキストノードも1要素としてカウントしているような挙動が見られましたので、ExtendScript側の不具合なのか、使い方が間違っているのかのどちらかになりそうです。

 

別方法での解決ができましたので、クローズします。

2 replies

s-onishiAuthorCorrect answer
Inspiring
February 21, 2024

NextElementDFSプロパティを使用する方法をやめて、TextItemのFTI_ElementBeginを使用する方法に変更すると、問題なく動作していました。

 

取得出来る要素の数が10倍程NextElementDFSの方が多いという差が発生しておりました。

要素内のテキストノードも1要素としてカウントしているような挙動が見られましたので、ExtendScript側の不具合なのか、使い方が間違っているのかのどちらかになりそうです。

 

別方法での解決ができましたので、クローズします。

s-onishiAuthor
Inspiring
February 21, 2024

追記です。

FrameMaker2022の場合は64bitだからか、落ちる容量は増加してそうでした。