Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 10全般 : Excel 2013)
マクロ""を実行できませんこのブックでマクロを使用できないか、またはすべてのマクロが無効になっている可能性があります。を解消したい
投稿日時: 21/10/13 10:40:58
投稿者: もみのき

Excelで時間計測してくれるものを作成しています。
ユーザーフォームでスタートボタンを押すと時間計測しストップボタンを押すとセルに合計時間が転記される仕組みです。
ユーザーフォームを起動中でもExcelを複数使用するためにスタートボタンをクリックすると非表示になるようにHideメソッドを組み込みました。
組み込んだ後他のExcelも使用は可能になりましたが、マクロ""を実行できませんこのブックでマクロを使用できないか、またはすべてのマクロが無効になっている可能性があります。というエラーが表示されます。
OKボタンを押した後表記は消えて時間計測のユーザーフォーム自体もそのまま使え、他のExcelも使えます。
なぜ使えているのにエラーが出てしまうのは全く不明です。
エラーが表示される原因や表示されないようにする方法があればご教示頂きたいです。
VBAは始めたばかりで超初心者です。
 
分かりやすく教えて頂けると幸いです!
よろしくお願いします。
 
ユーザーフォーム
Option Explicit
Public mOnTime As Date
Public wb As Workbook
Public ws As Worksheet
 
Private Sub ストップ_Click1()
' ストップボタンをクリックした際におこるイベント
'右上のコマンドをストップ_Click1にする
 
    Dim MaxRow As Integer '整数(Integer)型の変数MaxRowを宣言
    Set wb = Workbooks("時間計測ツール.xlsm")
    Set ws = Worksheets("タイム")
        MaxRow = wb.ws.Cells(Rows.Count, 1).End(xlUp).Row + 1 'MaxRowに最終行を代入
            wb.ws.Range("B" & MaxRow).Value = UserForm1.内容.Value
                                        
End Sub
 
Private Sub ストップ_Click()
 
 
    Set wb = Workbooks("時間計測ツール.xlsm")
' Set ws = Worksheets("タイム")
On Error Resume Next
    Call Application.OnTime(mOnTime, "スタート", , False)
            終了時間.Value = Time
            終了日.Value = Date
    Dim MaxRow As Integer '整数(Integer)型の変数MaxRowを宣言
        MaxRow = Cells(Rows.Count, 1).End(xlUp).Row + 1 'MaxRowに最終行を代入
            Range("A" & MaxRow).Value = 開始日.Value
            Range("F" & MaxRow).Value = 件数.Value 'F列のMaxRow行に、件数の値を代入
            Range("B" & MaxRow).Value = 内容.Value
            Range("C" & MaxRow).Value = 開始時間.Value 'E列のMaxRow行に、開始時間の値を代入
            Range("D" & MaxRow).Value = 終了時間.Value 'F列のMaxRow行に、終了の値を代入
            Range("E" & MaxRow).Value = 合計時間.Value 'G列のMaxRow行に、合計時間の値を代入
    内容.SetFocus 'Tabキーで下に移動させる(入力できるコマンドに限る)
    Call UserForm_Initialize 'UserFormを開いたときに強制でなるイベント
         Unload UserForm1
End Sub
 
Sub TimerProc()
    開始日 = Date
    開始時間 = Time()
End Sub
 
Private Sub 開始時間_Change()
    Call CalcTotal
End Sub
 
Private Sub スタート_Click()
    Call TimerProc
         mOnTime = Time() + TimeSerial(0, 0, 1)
    Call Application.OnTime(mOnTime, "スタート")
    UserForm1.Hide
 
End Sub
 
Private Sub 終了時間_Change()
    Call CalcTotal
End Sub
 
Private Sub CalcTotal()
    If IsDate(終了時間.Value) = True _
        And IsDate(開始時間.Value) = True Then
            合計時間.Value = Format((TimeValue(終了時間.Text) - TimeValue(開始時間.Text)), "hh:mm:ss")
        Else
            合計時間.Value = ""
    End If
            'もし単価と数量が数値でなければ金額は空白
            '金額=単価*数量
End Sub
 
Private Sub UserForm_Initialize() 'ユーザーフォームを開いたときに強制で起こるイベント
    Worksheets("タイム").Activate ' タイムを操作する
    Dim MaxRow As Integer
        MaxRow = Cells(Rows.Count, 1).End(xlUp).Row '最終行を取得
     If MaxRow > 6 Then
             内容.Value = Range("B" & MaxRow).Value '受注ID
             件数.Value = Range("F" & MaxRow).Value '件数
     End If
    Dim cMaxRow As Integer
    Dim aMaxRow As Integer
        cMaxRow = Worksheets("タスク一覧").Cells(Rows.Count, 1).End(xlUp).Row '会社名リストの最終行を取得
        aMaxRow = Worksheets("タスク一覧").Cells(Rows.Count, 6).End(xlUp).Row
    Dim i As Integer
    Dim a As Integer
     For i = 3 To cMaxRow '3行目から最終行を取得
        内容.AddItem Worksheets("タスク一覧").Range("A" & i).Value 'comboBoxに会社名リストを追加
     Next i
     For a = 3 To aMaxRow
        件数.AddItem Worksheets("タスク一覧").Range("F" & a).Value 'comboBoxに数字リストを追加
     Next a
End Sub
 
モジュール
Option Explicit
 
Sub ボタン4_Click()
UserForm1.Show vbModeless
End Sub
 

回答
投稿日時: 21/10/13 11:03:01
投稿者: QooApp

マクロ実行中のエクセルのアプリケーション内で、
新しいブックを呼び出したらマクロ実行状態なので動かないってことでしょうか。
 
タスクバーのエクセルアイコンから新しいExcelを立ち上げて、
アプリケーションを切り分けたら動作するような気がしますがどうでしょう。

投稿日時: 21/10/13 11:14:59
投稿者: もみのき

QooAppさん
ご回答ありがとうございます。
 
説明が拙くてすみません
業務上Excelを頻繁に利用することが多いためユーザーフォームを起動中に他のExcelが使用できるように非表示になるようにしました。
非表示にする前は別で開いているExcelを使おうとしてもクリックすらできない状態でした。
エラー表記後もマクロ自体は正常に動作していますが、スタートボタンを押すとエラーが必ず表記されてしまう状態です。
なのでエラーが表示されるのを解消したいです。
 

投稿日時: 21/10/13 11:19:53
投稿者: もみのき

QooAppさん
 
すみません補足ですが、タスクバーから新しくExcelを開くとそのExcelは使用可能でした!
ですが、既に開いているExcel等も使用できるようにはできないのでしょうか

回答
投稿日時: 21/10/13 12:01:07
投稿者: QooApp

※すみません、内容見飛ばして滅茶苦茶な内容書いていたので再掲します。
 
基本的な考え方としまして、1つのアプリケーションでマクロが1つ実行中の場合、
・エクセルの操作ができない
・他のマクロが起動できない
といった現象が発生します。
  
並行してプログラムを実行できないというルールがあるからですね。
聖徳太子のような複数並列処理は原則できません。
  
他のアプリケーションとしてExcelを起動すると、そのアプリケーションのExcelと元のアプリケーションのExcelは別々に動作するので一応マクロを並行して起動はできますが、相互に参照・書き込みなど行うとデッドロック(フリーズのような状態)やエラー(書き込めません)となります。
 
 
Hideのコマンドの部分で、ただ隠しただけで、実はユーザーフォームが生きているのではないかと思います。
 
Unload UserForm1でユーザーフォームを終了できるはずなので、Hideの行にブレークポイントを設置していただき、マクロ実行、Hideの部分まで操作を進める。
 
ブレークポイントの部分でマクロが停止し、編集画面がディスプレイに表示されるはずなのでF8を押してどこかでループ状態になってないか見れますか。
 
.showが開きっぱなしになって死んでないんじゃないかと思います。

回答
投稿日時: 21/10/13 12:19:01
投稿者: Suzu

もみのき さんの引用:
タスクバーから新しくExcelを開くとそのExcelは使用可能でした!
ですが、既に開いているExcel等も使用できるようにはできないのでしょうか

 
Excel の 構成として
 
 Excel Application 内に 複数のブックを開くことが可能です。
  ですが、マクロを実行する部分は、ブック毎ではなく、アプリケーションに対し 1つになります。
 
 今、ユーザーフォームは 非表示にしているとは言え、バックグランドにて マクロは動作してる状態です
 ですので、その ユーザーフォームのマクロを止めないと、
 同じ Excel Application に含まれる 他の ブックのマクロを実行できない状況であり、
 
 別の Excel Application を立ち上げ ブックA を開くと その ブックA のマクロは実行できる
 と言うのは、そういう状態なのです。
 
 
別案としては ユーザーフォーム側の 動作内に
DoEvents を入れれば、制御を OS に返すので、
他のブックを操作する事が可能になります。(マクロも可能)
 
 
Sub TEST()
  Dim s0 As Single
  Dim s1 As Single

  s0 = Timer
  s1 = s0 + 2000

  Do While s1 > s0
    [color=red]DoEvents[/color]
    ThisWorkbook.Worksheets("Sheet1").Range("A1").Value = s0
    s0 = Timer()
  Loop
End Sub

投稿日時: 21/10/13 12:55:20
投稿者: もみのき

QooAppさん
 
Private Sub UserForm_Initialize() 'ユーザーフォームを開いたときに強制で起こるイベント
    Worksheets("タイム").Activate ' タイムを操作する
    Dim MaxRow As Integer
        MaxRow = Cells(Rows.Count, 1).End(xlUp).Row '最終行を取得
     If MaxRow > 6 Then
             内容.Value = Range("B" & MaxRow).Value '受注ID
             件数.Value = Range("F" & MaxRow).Value '件数
     End If
    Dim cMaxRow As Integer
    Dim aMaxRow As Integer
        cMaxRow = Worksheets("タスク一覧").Cells(Rows.Count, 1).End(xlUp).Row '会社名リストの最終行を取得
        aMaxRow = Worksheets("タスク一覧").Cells(Rows.Count, 6).End(xlUp).Row
    Dim i As Integer
    Dim a As Integer
     For i = 3 To cMaxRow '3行目から最終行を取得
        内容.AddItem Worksheets("タスク一覧").Range("A" & i).Value 'comboBoxに会社名リストを追加
     Next i
     For a = 3 To aMaxRow
        件数.AddItem Worksheets("タスク一覧").Range("F" & a).Value 'comboBoxに数字リストを追加
     Next a
End Sub
 
上記の件数.AddItem Worksheets("タスク一覧").Range("F" & a).Value 'comboBoxに数字リストを追加の部分がループしているようです。
 
Suzuさん
別案ありがとうございます。試してみます[/b]

回答
投稿日時: 21/10/13 13:28:05
投稿者: QooApp

For a = 3 To aMaxRow
        件数.AddItem Worksheets("タスク一覧").Range("F" & a).Value 'comboBoxに・・・
Next a

 
変数 a ですが、タスク一覧シートのF列でリストとして存在する行数分繰り返し入力しているようですが、
この変数 a の値はおそらく変動していると思います。
 
変数 a の値がF列一覧の末尾までF8を連打いただくか、すぐ下、「End Sub」にブレークポイントを設定してからF5キーを押してみてください。
 
もし、
・for文ループから脱却できてない
・変数 a の値が変わってない(F8で操作している一時停止中ならばカーソルを変数に合わせれば値が見れます)
とかであれば教えてください。
 
見た感じループ自体は行数分繰り返したあと、正常に脱却してくれそうです。

回答
投稿日時: 21/10/13 16:59:40
投稿者: Suzu

引用:
マクロ""を実行できませんこのブックでマクロを使用できないか、またはすべてのマクロが無効になっている可能性があります。というエラーが表示されます。

 
あ。。再現できました。
 
 Call Application.OnTime(mOnTime, "スタート")
 
この、「スタート」という引数ですが、プロシージャ名を指定します。
「スタート」という プロシージャ が存在しない場合、同様のメッセージが表示されました。
 
「スタート」というプロシージャが存在するか確認ください。

回答
投稿日時: 21/10/13 17:05:54
投稿者: Suzu

直接は関係ありませんが、
 
ループ処理を使わずに リストのアイテムを追加 する方法。
AddItem を使うのではなく
 ・Listプロパティー に セル値を参照した配列を指定
 ・RowSource プロパティー に セルを指定
 
どちらかを使用すればループ処理は行わずに済みます。
 
 
参考URL
 
よねさんのWordとExcelの小部屋
コンボボックスの使い方:Excel VBA入門
http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/vba_userform05.html

投稿日時: 21/10/13 17:32:19
投稿者: もみのき

Suzuさん
 
改善されました!ありがとうございます。
スタートというプロージャー名は存在しなかったので名前を変更したら直りました。
他のアドバイスも頂きありがとうございます。この後見てみます!
 
QooAppさんも教えて下さりありがとうございました。