[[20111226160753]] 『マクロの中でマクロ実行』(ちょこ) ページの最後に飛ぶ

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

 

『マクロの中でマクロ実行』(ちょこ)

 お久しぶりです。
 前回の質問が題名とかけ離れしまいすぎたので新しく立てました。
 前回の質問はこちらになります。

[[20111209105823]] 

 ぶらっと様のコード試しました。
 なるほど〜!!とただただ関心の一言です。

 そしてあつかましく新たな質問があります。
 題名の通りマクロの中でマクロを実行したいのです。
 前の質問で1つ1つのやりたいマクロは作れたのですが、
 それを連続して実行したいのです。
 マクロの自動記録でやったらいいやん。と思われるでしょうが
 一つ目のマクロはブックを開いたときに動作して欲しいので無理でした。

 自動記録ででてきたコードを引っ張ってきて
 オープンマクロのコードに貼り付けてみたもののうまくいかず...。

 どうしたら2つ目のマクロから3つ目が呼び出せますか?
 Call マクロ名 だとだめなんでしょうか?

 3つのマクロを合体させるほうが簡単ならそれでもかまいません。
 よろしくお願いします。(実際は3つですが..)

 1つ目のマクロ

 Private Sub Workbook_Open()
    If ActiveSheet.Name = "出荷前" Then Sheet1_Open_Macro

End Sub

 2つ目のマクロ

 Sub Sheet1_Open_Macro()

 Dim FoundCell As Range
 Dim First As Range
 Dim a As Long
 Dim b() As String
 Dim buttom As Variant
 Dim Foundrng As Range

 Set FoundCell = Range("E:E").Find(What:=Format(Now(), "yyyy/mm/dd"),  After:=Range("E" & Rows.Count), LookIn:=xlValues)
    If FoundCell Is Nothing Then
        MsgBox "今日は出荷なし!"
         Exit Sub
    End If
 Set First = FoundCell
 ReDim b(1 To Range("E" & Rows.Count).End(xlUp).Row)
    Do
        a = a + 1
        b(a) = FoundCell.Offset(0, -3).Value & " " & FoundCell.Offset(0, -2)
        If Foundrng Is Nothing Then
         Set Foundrng = FoundCell
        Else
         Set Foundrng = Application.Union(Foundrng, FoundCell)
        End If
        Set FoundCell = Range("E:E").FindNext(FoundCell)
    Loop While FoundCell.Address <> First.Address
 ReDim Preserve b(1 To a)
        buttom = MsgBox(FoundCell & "出荷予定は以下です" & vbLf & vbLf & Join(b, vbLf) & vbLf & vbLf & "出荷しますか?", vbYesNo, "出荷確認")
    If buttom = vbYes Then
      Foundrng.Offset(, 1) = "済"
    End If
 Set FoundCell = Nothing
 Set First = Nothing
 Set Foundrng = Nothing

 End Sub

 3つ目のマクロ

 Sub Sample()
    Dim FoundCell As Range
    Dim First As Range
    Dim v() As Range
    Dim v2() As String
    Dim k As Long
    Dim Button As Integer
    Dim Foundrng As Variant

    ReDim v(1 To Range("D" & Rows.Count).End(xlUp).Row)
    ReDim v2(1 To UBound(v))

    Set FoundCell = Range("D:D").Find(What:=Format(Now() + 1, "yyyy/mm/dd"), After:=Range("D" & Rows.Count), LookIn:=xlValues)
    If FoundCell Is Nothing Then Exit Sub

    Set First = FoundCell

    Do
        If FoundCell.Offset(, 2).Value = "" Then '←追加コードです
            k = k + 1
            Set v(k) = FoundCell
            v2(k) = FoundCell.Offset(0, -2).Value & " " & FoundCell.Offset(0, -1)
        End If
        Set FoundCell = Range("D:D").FindNext(FoundCell)
    Loop While FoundCell.Address <> First.Address

    If k > 0 Then
        ReDim Preserve v(1 To k)
        ReDim Preserve v2(1 To k)

        If MsgBox("以下が明日納期です" & vbLf & vbLf & Join(v2, vbLf) & _
                vbLf & vbLf & "出荷しますか?", vbYesNo, "出荷の確認") = vbYes Then
            For Each Foundrng In v
                    Foundrng.Offset(, 2).Value = "済"
            Next
        End If
    Else
        MsgBox "明日納期のもので未処理のものはありませんでした"
    End If

    Erase v
    Set FoundCell = Nothing
    Set First = Nothing

 End Sub


 新規ブックに以下を貼り付けて、Test1 および Test2 を実行してみて。
結果は同じだけど、(ちょこ) さんがやりたいのは Test1 のほうかな?

 Sub Test1()
    Call Test1_1
    Call Test1_2
    Call Test1_3
 End Sub

 Private Sub Test1_1()
    MsgBox "Test1_1 です"
 End Sub

 Private Sub Test1_2()
    MsgBox "Test1_2 です"
 End Sub

 Private Sub Test1_3()
    MsgBox "Test1_3 です"
 End Sub

 Sub Test2()
    Call Test2_1
 End Sub

 Private Sub Test2_1()
    MsgBox "Test2_1 です"
    Call Test2_2
 End Sub

 Private Sub Test2_2()
    MsgBox "Test2_2 です"
    Call Test2_3
 End Sub

 Private Sub Test2_3()
    MsgBox "Test2_3 です"
 End Sub

 (ぶらっと)

 アップされたコードをよく見ていなかった。

 ・まず、Openイベントで実行するのはいいんだけど、ブックを開いた時のアクティブシートが
 "出荷前" じゃなかったら実行はされないよ。 
 ・で、"出荷前"だったとしたら、Sheet1_Open_Macro は実行されるはずだけど?
 ・ところで、Workbook_Open 以外のマクロはどこにかいてあるの?

 (ぶらっと)

 おはようございます。
 記述されたコードなのですが私がやりたいのは
 おっしゃるとおりテスト1のほうです。
 Openイベントのなか(又はSheet1_Open_Macro)のなかで
 Sub Sample()のマクロが実行されて欲しいのです。

 >ブックを開いた時のアクティブシートが
 "出荷前" じゃなかったら実行はされないよ。

 ・あ、あー...。そうですね、、、sheet2を開いた状態で保存してブックを
 開いた時"出荷前"にしても起動しないですね(´・й・`)
 sheet2はほぼ開くことがないから考えてなかった...
 ん?考えてたから If ActiveSheet.Name = "出荷前" Then にしたはずだけど・・・。思わぬ誤算;ぬ〜

 >"出荷前"だったとしたら、Sheet1_Open_Macro は実行されるはずだけど?

 ・そうです。
 このマクロ1からマクロ2はうまく実行されるのですが
 マクロ2が終わった後マクロ3を呼び出して続けて実行して欲しいのにうまくいかないんです。

 >ところで、Workbook_Open 以外のマクロはどこにかいてあるの?

 ・色々試したんですけど ThisWorkbook にマクロ1と2が、マクロ3は今はSheet1(出荷前)にいて
 手動で実行させています。

 希望は、

 @ブックを開いた時今日出荷分を表示(マクロ1→マクロ2) 動作OK
 A続けて明日納期のものを表示(マクロ3) 

 となって欲しいです。
 欲を言うなら「ブックを開いた時"出荷前"ならば・・・」ではなく、
 「"出荷前"を開くのが今日一回目ならば・・・」にできたら
 Sheet2で保存しても"出荷前"を開けばマクロが実行されるし
 「"出荷前"を開いた時・・・」にしたときみたいにSheet2を開いて戻って来た時
 また実行されるということがないからいいなぁと思ったのですが、
 今のところ今のコードでも問題はあまりないのでかまわないです^^

 よろしくおねがいします

 (ちょこ)


 まず
 >このマクロ1からマクロ2はうまく実行されるのですが
 >マクロ2が終わった後マクロ3を呼び出して続けて実行して欲しいのにうまくいかないんです。

 なぜかというと、マクロ1(Openプロシジャ)でマクロ2(Sheet1_Open_Macro)にはとんでいるけど
Sheet1_Open_Macro では、自分の処理を終えたら、終了しているので、そのままマクロ1に戻る。
で、マクロ1(Openプロシジャ)では、戻った後、何もしないで、End SUb。
だからマクロ2は実行されない。なので、Sheet1_Open_Macroを実行させた後、Sampleも実行させるようなコードが必要。

 で、99%の人は、まず「マクロ」からVBAの勉強を始めると思うので、「ついつい、シートモジュール」にコードを書くね。
だめじゃないんだけど、シートモジュールは、ちょっと「くせもの」。その1つが、そこに書かれたマクロの呼び出し方法。
Sample あるいは Call Sample ・・・だめなんだね、これが。コンパイルレベルで、Sampleが見当たらないよと怒られる。
これを呼び出そうとすると、Sheet○.Sample とか Call Sheet○.Sample としなきゃいけない。
で、このSheet○は、「シート名」(現住所)ではなく、シートが生成された時に裏で割り振られる、シートの本籍値ともいうべき
「コード名」(VBE画面の左上のプロジェクトエクスプローラで、Sheet1(出荷前) といったように表示される左側)

 個人的には、この記述は問題が多いと思うので使わない。
それより、「標準モジュール」というくらいだから、通常のマクロは「標準モジュール」に書くのがいいよ。
ここのマクロなら、単純に、Sample あるいは Call Sample で呼び出すことができる。

 さて、薀蓄はこれくらいにして、本題だけど、やりたいことは
・ブックを開いた時に、その時のアクティブシートがなんであろうと、マクロ1とマクロ2を自動実行させたい。
・その日、2回目に開くようなことがあったとしたら、その時には、自動実行させたくない。

 こんなこと?
で、開いた後、何らかのタイミングで、Sheet1_Open_MacroやSampleは実行させることはある?それとも、ない?
それによって、Sheet1_Open_MacroやSampleを記述する場所を考える。(少なくともシートモジュールじゃないけど)

 追加)Sheet1_Open_Macro と Sample が相手にするシートは、それぞれ、どのシート?
   (Sheet1_Open_Macro は 出荷前 だろうけど)
   それと、Sheet1_Open_Macro で "今日は出荷予定なし" となった時も、続けて Sampleを実行するの?
   それとも、その場合は、実行しないの?

 (ぶらっと)

 ↑の質問だけど、Sampleも"出荷前"シートを相手にするんだったような記憶が。
 ということなら、以下ではいかが。
・まず、Sheet1_Open_Macro と Sample は、標準モジュールに引越し。
 (開いた時だけの処理ならThisWorkbookモジュールでもいいけど、単独で使うことがあれば標準モジュールのほうが扱いやすい)
・で、これらマクロでは「ActiveSheet」を処理対象にしている。それらに全て、Sheets("出荷前"). とシート修飾すべきだと
 思うけど、面倒というか、大変だろうから、それぞれのマクロの最初に Sheets("出荷前").Select をいれて逃げよう。
・で、Openイベントは以下のように。
 (今日、最初に開いたかどうかということじゃなく、今日、開かれて保存されたかどうかを判定。開かれていても
  保存してなければ、実際には処理は行われていないので)

 Private Sub Workbook_Open()
    Dim d1 As Date
    Dim d2 As Date
    d1 = Date
    d2 = Int(ThisWorkbook.BuiltinDocumentProperties("Last Save Time"))
    If d1 = d2 Then Exit Sub   '今日、処理して保存されていればスキップ
    Call Sheet1_Open_Macro
    Call Sample
 End Sub

 あぁ、それと、気になるんだけど。
Sheet1_Open_Macro のほうは、対象データがない場合、"今日は出荷なし!" とメッセージ。
だけど、Sampleのほうは、メッセージなしでExit Sub。ここにも、"明日の出荷予定なし!" とメッセージいれたらどうだろう?

 (ぶらっと)

お返事を書いてる間に書き込みが!!;
 とりあえずせっかくなので載せておきます^^

 >Sample あるいは Call Sample ・・・だめなんだね、これが。
 >コンパイルレベルで、Sampleが見当たらないよと怒られる。

 そう!そうなんです!怒られちゃって呼び出せなくて今手動状態です(;_+)

 ぶらっと様のご指示の通り標準モジュールにコードを貼り付けて
 call Sample で呼び出してみたのですがエラーは出ないのになぜかうまく表示されてくれません。
 End Sub の前に記述してみたけどここじゃだめなんですか?

 >ブックを開いた時に、その時のアクティブシートがなんであろうと、マクロ1とマクロ2を自動実行させたい 

 ・そうですね。Sheet2の場合でも"出荷前"シートのデータを検索し表示してくれると助かります。
 またはSheet2の場合は実行しないで"出荷前"シートを開いた時のみ実行。

 >その日、2回目に開くようなことがあったとしたら、その時には、自動実行させたくない。

 ・これはまさにその通りです。

 >開いた後、何らかのタイミングで、Sheet1_Open_MacroやSampleは実行させることはある?それとも、ない?

 ないです。

 >Sheet1_Open_Macro と Sample が相手にするシートは、それぞれ、どのシート?
   (Sheet1_Open_Macro は 出荷前 だろうけど)

 ・両方とも"出荷前"です。

 >Sheet1_Open_Macro で "今日は出荷予定なし" となった時も、続けて Sampleを実行するの?
   それとも、その場合は、実行しないの?

 ・出荷なしとなった場合もSample実行させたいです。
 なぜなら出荷予定の記入漏れで今日出荷がなかった場合でも明日納期のものがあればその日に出荷品しなければいけないからです。

(ちょこ)


 >Sheets("出荷前").Select をいれて逃げよう。
 なんか笑っちゃいました。
 マクロって難しいけどぶらっと様くらいになれば逃げ道も作れちゃうんですね。

 提示していただいたコードを記述して実行してみたところ、
 もう既に開いて保存してしまった後だったので

 If d1 = d2 Then Exit Sub   '今日、処理して保存されていればスキップ

 ここで抜けてしまって(ここ・・・ですよね?;)なにも起こらず;
 明日朝一番に起動するのが楽しみです!^^

 >Sheet1_Open_Macro のほうは、対象データがない場合、"今日は出荷なし!" とメッセージ。
 だけど、Sampleのほうは、メッセージなしでExit Sub。ここにも、"明日の出荷予定なし!" とメッセージいれたらどうだろう?

 ここはただ単にないならでなくていーや!って感じのデータなんでメッセージ表示してないんです;
 「『今日は出荷なし』だったけど明日納期のあるよ?いいの?出荷しないの?」って意味合いだから、
 明日納期のものがなければ「明日納期のものないから特に言うことないよー」みたいな感じで
 メッセージ入れてません;

 Sheet1_Open_Macro はメッセージなしでExit Subにしてしまうと作動したかわかんないんでメッセージ表示してます^^

 Sampleのほうもあってもいんですけどなんか、うん。なんとなく。
 あったほうがいいですかね?

  (ちょこ)


コメント返信:

[ 一覧(最新更新順) ]


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