[[20210628170606]] 『Application.Ontimeで別ブックマクロ実行、引数指』(VBA辛い) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『Application.Ontimeで別ブックマクロ実行、引数指定したい』(VBA辛い)

お世話になります。

先日の質問[[20210611111706]]をもとに作成していて行き詰まったところなのですが、
別ブックをApplication.OnTimeで実行するときに、引数を指定したいのですがうまくいきません。
現状、
Application.OnTime Now(), "[ブックのフルパス]!'[マクロ名]'"
での実行は確認できたのですが、引数を指定したく、
Application.OnTime Now(), "[ブックのフルパス]!'[マクロ名] [引数1] , [引数2]'"
としていますが、「1004 指定した名前のアイテムが見つかりませんでした。」のエラーが出ます。

アポストロフィの位置を移動して試しましたがうまくいきません泣
どうしたら良いでしょうか、よろしくお願いします。

< 使用 Excel:Excel2013、使用 OS:Windows10 >


[[20170125155858]] 『Application.OnTimeエクセルAlarm時計』(マリオ)
 のβさんの整理メモを参考にしてみてください。
      ↓
 (β) 2017/01/26(木) 08:32

(半平太) 2021/06/28(月) 17:39


回答ありがとうございます。

質問する前にそちらを参考にして、
フルパスの前にアポストロフィを入れたりしましたが、
同様のエラーが出てしまいます。

マクロ名をアポストロフィでくくって2重にしたりと試してみましたが
うまくいきません。
指定のブック以外のマクロを動かしたくないので、フルパス指定しています。
なんとかできる方法はないでしょうか。
よろしくお願いします。

(VBA辛い) 2021/06/29(火) 15:39


 > ・『文字列』なので、引数として変数を指定することはできない。あくまで変数の『中身』をセット。
     ↑
 これに該当していないですか?

(半平太) 2021/06/29(火) 17:02


 >「1004 指定した名前のアイテムが見つかりませんでした。」のエラーが出ます。

 ですか・・引数の渡し方は良いが、その引数が適切な値じゃないってことはないですか?

(半平太) 2021/06/29(火) 17:19


ありがとうございます

引数が長過ぎるかと思って短くしたり、
ファイルをフルパスではなくしたりと
いろいろ試してみましたが、マクロを実行できませんでした。
Application.Ontimeで「別ブック」の「引数付き」のマクロの起動はできなさそうです。

ちょっと半分諦めてますが、解決方法あればよろしくお願いします。
(VBA辛い) 2021/07/01(木) 15:50


 文字列を結合する式について理解ができていないだけだと思います。

 実際のコードを書かないと具体的な指摘もできないですよ
(´・ω・`) 2021/07/01(木) 15:57

	'Book1の標準モジュール
	Sub sample(s As String)
	    MsgBox s
	End Sub

        'Book2の標準モジュール
	Sub test()
	    Application.Run "Book1!'sample ""この文字が表示される""'"  
	End Sub

 Runに渡す文字列をどう作るかが問題なんですよね?
(´・ω・`) 2021/07/01(木) 16:04

 別ブックではないけど。

 Sub aaa()
   HypRR = 3
   HypRL = 5
   HypSh = "Sheet3"
   CR = 7
   CL = 10
                 '↓マクロ名の後に半角スペース必   ↓文字の場合は注意
   St = "'CELLSECT " & HypRR & "," & HypRL & ",""" & HypSh & """," & CR & "," & CL & "'"
   Application.OnTime Now(), St
 End Sub

 Sub CELLSECT(RgR, RgL, WSn, CR, CL)
   Application.Goto Reference:=Sheets(WSn).Cells(RgR, RgL), scroll:=True
   Cells(RgR, RgL).Offset(, Int((CL - CR) / 2)).Select
 End Sub
(BJ) 2021/07/01(木) 16:40

´・ω・`さん

サンプルマクロありがとうございます。
まるまるコピーして実行しら
「実行時エラー1004 C:\Users\****\Documents\Book1.xlsxが見つかりません。」
と出てしまいましたが、「Book1.xlsm」と指定してやるとすんなり実行されました。
しかし、そこをフルパスで指定するとまた実行できないくなってしまって・・・

と、ここからいろいろ試したところなんとなく原因がわかったのでまとめます。

1つめ
実行したいマクロブックのフルパスはアポストロフィ(')でくくる。
'[マクロフルパス]'!'[マクロ] [引数],[引数]'

2つめ
引数が長すぎると、内部的にどこかで切れてしまう。
自分の場合、引数2つともフルパスで、短くすれば通ったので
どこかで切れてしまったと考えられる。

という感じの罠がありました。
Application.Runの引数の文字数制限が何文字なのかわかりませんが
引数をフルパスで渡したかったのでちょっと考え直さないといけません・・・。

とはいえ、みなさんのおかげで原因がわかりました。
ありがとうございます!

(VBA辛い) 2021/07/02(金) 14:13


ちなみにですが、引数のところでフルパスを指定したいときはアポストロフィなしでもOKです。
他の方がこの問題に直面するかわかりませんが、参考のため。
(VBA辛い) 2021/07/02(金) 14:18

 ちょっと遅い反応で恐縮です。

 Application.Ontime Now(), "test"
 のtestのところを、別ブックのプロシージャにしたいというのが話のスタート。

 コメントを受けて、testを直接修正するよりも、
 testの中で、Application.Run 別ブックのマクロ とすればよい、
 と方針転換。

 で、私の質問コメントは以下です。
 最終的に、引数の文字列数がネックになるとのことですが、
 私の手元では再現しません。(256かと思ったが、そうでもないし1000でもOKだった)

 Application.Runに渡す引数の文字列の話というより、
 受けた側のプロシージャの話の予感がするんですが、
 再現する情報を挙げてもらうことはできますか?
(γ) 2021/07/05(月) 09:03

 ちなみに、
 Application.Ontimeに渡すプロシージャに引数を追加する方法は、
 過去ログのβさんの発言が有益でした。

 Application.Run について若干まとめて見ました。
 私の認識は、あっていますでしょうか。

  (1)開いていなければ、自動で開きます。
     カレントフォルダでなければ、もちろんフルパス指定が必要。
  (2)ブック名にspaceを含む場合等は、
     ブック名(フルパス)を ' と ' で囲む必要がある。
          ex. Application.Run  "'D:\MyDocuments\20210701 Book1.xlsm'!test" などとする。
  (3)ブック名の拡張子xlsmは省略可能(推奨しない)

     【以下で単に"ブック名"としたのは標語的であって、上記を満たすことが前提。】

  (4)private属性のマクロでも実行可能
  (5)同名のマクロが複数ある場合は、module名を指定しないとエラーとなる。
       Application.Run  "ブック名!module1.test" などとする。
  (6)シートモジュール、Thisworkbookモジュールに記載のマクロも実行可能。
       Application.Run  "ブック名!Sheet1.test"
       Application.Run  "ブック名!ThisWorkbokk.test"

  (7)引数を渡す(引数の個数は任意)
       Application.Run  "ブック名!test", arg1
(γ) 2021/07/05(月) 09:06

γさん

文字列数の件ですが、
上で他の方が提示していただいたサンプルを改変して載せます。
Book2のfile2かfile3のところを増やすと
1004 指定した名前のアイテムが見つかりませんでした。
となります。

'Book1の標準モジュール
Sub sample(s As String, Optional s2 As String = "")

    MsgBox s
    MsgBox s2
End Sub

    'Book2の標準モジュール
Sub test2()

    Dim file1 As String
    Dim file2 As String
    Dim file3 As String
    file1 = ".........\Book1.xlsm"     'フルパス、100文字ぐらいあります。
    file2 = "\abcdefghijklmnopqrstuvwxyz\abcdefghijklmnopqrstuvwxyz\abcdefghijklmnopqrstuvwxyz\abcdefghijklmnopqrstuvwxyz"
    file3 = "\abcdefghijklmnopqrstuvwxyz"

    Application.OnTime [Now()+"0:00:01"], "'" & file1 & "'!'sample """ & file2 & """,""" & file3 & """'"

End Sub

もしかすると、Excel64bit/32bitで挙動が違うということはありますかね。
文字列型なので関係ないという認識ですが。
私の環境は32ビットです。

(VBA辛い) 2021/07/05(月) 15:40


 短い方のパスを使えば良いんじゃないですかね?
 ダメだろけど。
 MsgBox CreateObject("Scripting.FileSystemObject").GetFile("フルパスファイル名").ShortPath
(BJ) 2021/07/05(月) 16:12

file2,file3に対してはどんな操作がsampleの中でされるのでしょうか。
spaceが入っていたり、ファイルパスとして無効なものが入っていたりということはないですか?
ファイル存在のチェックを事前に行うことはできますか?
# 32bitであれば問題はないと思います。
# それと Application.Runを経由する話はなくなったのですか?
# OnTimeの文字数制限について私は検証していません。
(γ) 2021/07/05(月) 16:37

BJさん
それで受け側が動けば問題ないですが・・・
workbook.openで開いてるっぽいですがまだ詳しく見れてません

γさん
もともとOntimeでやりたいというのを表題でも書いてありますが、
頂いたサンプルがRunだったのでそちらでも一緒だと思い検証していました。
文字が増えるとエラーを出すのはRunもOntimeも同じです。
Runの場合は'Run'メソッドは失敗しました'_Application'オブジェクト
と出ます。

サンプルを見てもらえばわかりますが、スペースなしでもエラーが出ます。
また、上記サンプルで引数を少なくすれば実行できるので、ファイルパスの問題ではありません。

(VBA辛い) 2021/07/05(月) 17:23


事象がこちらでは再現実行できないので、何とも言えませんが、
単に文字列の長さが問題であれば、その旨のメッセージが出るはずとおもいませんか?
sampleというプロシージャとの関係においてエラーが出ているのではないでしょうか。

>上記サンプルで引数を少なくすれば実行できるので、ファイルパスの問題ではありません。
引数の数ですか?
文字列の長さですか?
長さを自由に変更できるようなものなんですか?ファイルパスではないんですか?
そのあたりがこちらにはよく理解できていません。
(γ) 2021/07/05(月) 17:42


ネットで検索しましたら、
VBAで扱えるネットワークパス名は256文字が上限だそうです。
BJさん提案のショートパスの利用をお薦めします。

(γ) 2021/07/05(月) 17:51


ネットワークは余計でした。

(γ) 2021/07/05(月) 17:54


訂正
また、上記サンプルで引数を少なくすれば実行できるので、 少なくすればではなく短くすればの間違いです。

上記のスクリプトで、実際にフルパスを指定しているのはfile1だけです。
また、
file3 = "\abcdefghijklmnopqrstuvwxyz\abcdefghijklmnopqrstuvwxyz"
ここの文字数をこのように増やしても再現されませんでしたか?
これはパスではなくただの文字列です。
これで実行できるというのであれば環境の問題としか言えませんね・・・

(VBA辛い) 2021/07/06(火) 11:43


 いやあ、話が噛み合わないなあ、と思っていましたが、私のミスでした。
 2021/07/05(月) 15:40の発言をまるまる見過ごしていました。どうも失礼。

 事象再現しました。
 Book1のsampleプロシージャはそのままで、以下を実行しました。
 OnTimeメソッドの第二引数 s に渡す文字列が256文字以上になるとそのような
 エラーになりますね。詳細調べる元気はありませんが、仕様ということなんでしょうね。

 Sub testA()
    Dim file1 As String
    Dim file2 As String
    Dim file3 As String
    Dim s As String

     file1 = "Book1.xlsm"     'フルパス、100文字ぐらいあります。
     file2 = "\abcdefghijklmnopqrstuvwxyz\abcdefghijklmnopqrstuvwxyz\abcdefghijklmnopqrstuvwxyz\abcdefghijklmnopqrstuvwxyz"
     file3 = Application.Rept("a", 120) ' sの文字列合計が255までは正常動作
    ' file3 = Application.Rept("a", 121) ' sの文字列合計が255を超えるとエラー

     s = "'" & file1 & "'!'sample """ & file2 & """,""" & file3 & """'"
     Debug.Print Len(s); s
     Application.OnTime [Now()+"0:00:01"], s
 End Sub
 s の中で! の次に'を置く意味が理解できませんが、ともかく再現はできました。

 私でしたら、Application.Runを使って書きます。
 こちらなら、引数をカンマで区切って渡すだけですから、
 Ontime利用と違って構造が簡単になり、
 文字列作成に神経を使うこともありません。

 Dim file1 As String
 Dim file2 As String
 Dim file3 As String

 Sub testB()
     Dim s As String

     file1 = "Book1.xlsm"     'フルパス、100文字ぐらいあります。
     file2 = "\abcdefghijklmnopqrstuvwxyz\abcdefghijklmnopqrstuvwxyz\abcdefghijklmnopqrstuvwxyz\abcdefghijklmnopqrstuvwxyz"
     file3 = Application.Rept("a", 500) ' sの文字列合計が256を超えても問題ない

     Application.OnTime [Now()+"0:00:01"], "test3"
 End Sub

 Sub test3()
     Application.Run file1 & "!sample", file2, file3
 End Sub

(γ) 2021/07/06(火) 14:14


γさん

検証ありがとうございます。
やはりOntimeに文字列制限があるようですね。

今回親質問で、マクロを起動してから自ブックを閉じたいということで
Ontimeで時間差を作っていました。

他の方法だと、できるかわかりませんがCreateObjectで別インスタンスでマクロを実行、ということも考えていましたが、ちょっといま試していません。
これは違う質問になってしまいますので、ここまでにしようと思います。

すみません、長々とありがとうございました!

(VBA辛い) 2021/07/06(火) 15:11


念のため申し上げるが、OnTimeを否定しているわけではないですよ。
検証テストでも書いていますが、OnTimeを使いつつ、
Application.Runを併用することで、文字列制限にも抵触せず、
しかも引数回りをスッキリ書ける、という話です。
(γ) 2021/07/06(火) 16:32

 備忘録としてメモしておきます。  
 ◆◆◆まとめ◆◆◆
 (A) Application.Ontime の第二引数にプロシージャとともに引数を渡す場合の書き方。
  ・まず、この文字列の先頭と最後に ' (シングルクォーテーション) を入れる
  ・この文字列の プロシジャ名とそのあとの引数の間には半角スペースを入れる
  ・引数が複数あれば、引数,引数,引数 と、 ,(カンマ)連結をする
  ・『文字列』なので、引数として変数を指定することはできない。あくまで変数の『中身』をセット。

  たとえば 与えるべき文字列が 'ProcA "abc",123,"def"' だった場合、
  Sub Test1()
     Application.OnTime Now(), "'ProcA ""abc"",123,""def""'"
  End Sub
  (■留意点■
   ・第二引数の文字数は255文字が上限。それを超えるとエラ-となる。
     (もともと、パス+プロシージャ名なので、パスに準じた制約が課されたものと想像される)
   ・これを避けるには、OnTimeでは引数無しのプロシージャを指定し、
     そのプロシージャの中で、Application.Runを使って引数指定すれば、制限は実質的に緩和される。
     (つまり、プロシージャを除いた引数は、カンマで分離された独立した引数となり、
       合計で255文字という上限からははずれることになるため。)  

 (B)Application.Run について 
   (1)指定したプロシージャのあるブックが開いていなければ、自動で開かれる。
      カレントフォルダでなければ、もちろんフルパス指定が必要。
   (2)ブック名にspaceを含む場合等は、
      ブック名(フルパス)を ' と ' で囲む必要がある。
        ex. Application.Run  "'D:\MyDocuments\20210701 Book1.xlsm'!test" などとする。
   (3)ブック名の拡張子xlsmは省略可能(推奨しない)
      【以下で単に"ブック名"としたのは標語的であって、上記を満たすことが前提。】
   (4)private属性のマクロでも実行可能
   (5)同名のマクロが複数ある場合は、module名を指定しないとエラーとなる。
        Application.Run  "ブック名!module1.test" などとする。
   (6)シートモジュール、Thisworkbookモジュールに記載のマクロも実行可能。
        Application.Run  "ブック名!Sheet1.test"
        Application.Run  "ブック名!ThisWorkbokk.test"
   (7)引数を渡す(引数の個数は任意)
        Application.Run  "ブック名!test", arg1
(γ) 2021/07/06(火) 19:35

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.