[[20200331141558]] 『フォームコントロールとActiveXコントロール』(ブリーフマスオAV) ページの最後に飛ぶ

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

 

『フォームコントロールとActiveXコントロール』(ブリーフマスオAV)

はじめまして。
問題は解決しているのですが(偶然に)理屈が分からないので答えてくれる方、ネット上の文献を紹介してくれる方がいればありがたいと思い投稿しました。

シート上にボタンを配置しました。シートチェンジしてユーザーフォームを読み込むだけの簡単な命令なので、特に何も考えずフォームコントロールからボタンを選択し、先程記述した命令を入れました。

押せば普通に動いてくれるのですが、呼び出したユーザーフォーム上で、新しいブックに現状のシート内容をコピーして上書き保存した後、ボタンの配置してあるシートに戻った時に、シート上に配置しているボタンが押せなくなります。

シート上のセルを適当に押して選択すればボタンは押せるようになるので、特に気にしていなかったのですが、別の利用者から改善を求められたので、ユーザーフォームを閉じる際にシート上のA1セルを選択する命令を追加しました。
デバッグモードでは問題なくセルが選択されボタンも押せるのですが、普通に動作させると、ブックやシートを丁寧に指定しても何故かこの命令をすっ飛ばしてしまいます。

八方塞がりの日々が続いていたのですが、先程何気なくボタンをActiveXコントロールに変更し同じ命令を入れてやった所、セル選択の命令を削除しても問題無くボタンが押せるようになりました。

ネット上では「簡単な命令ならフォームコントロール、複雑なマクロならActiveX」や、「ActiveXはバグが・・・」とか書いてありましたが、上記の問題に似たような事例の書いてある文献にたどり着けなかったので、どなたか分かる方ご教授の程、宜しくお願いします。

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


実際のコードを書いてもらうと、原因が判るかも知れません。 細かい部分をどうしているのか…。 ありがちなのは、アクティブなシートやセルに依存したコードを書いていて、シートを切り替えると想定外の動きをする事。 Excelのバグの前に、自分のコードを疑ってみてください。

例えば、ユーザーフォームは処理が終わった後、UnLoadせずにHideしているとかありませんか? Hideではオブジェクトが解放されず、見えないだけで、ユーザーフォームが存在したままになります。 あと、モーダル表示にしたか、モーダレス表示にしたかも大事。

コードに問題がない場合、Office関連アプリの新旧混在が原因でおかしくなる事もあります。 この場合は、マクロの編集画面で、「参照設定」が全てのPCで同じになっているか確認しましょう。(フォームコントロールのオブジェクトは、Excel ではなく、Office Object Library に依存するため)
(???) 2020/03/31(火) 15:12


???さん、返信ありがとうございます。

コードはかなり長いので端折って書かせて頂きます。
あと、モードレス表示にはしていません。

Private Sub CommandButton5_Click()

    <中略>

    Call HOZON

    Workbooks("表.xls").Worksheets("印刷").Activate
    Range("A1").Select

    Unload UserForm1

End Sub

Private Sub HOZON()

   <中略>

  '品目コードの頭に「区分と-(ハイフン)」をつける

    Call KUBUN

   <中略>

  Sheets("印刷").Copy
  On Error Resume Next

  '保存する前に、別の名前やフォルダに変更されている場合があるので、

    '保存するシートの「保存名」とパス記入セルを更新してやる
    Cells(1, 9) = phn
    Cells(2, 3) = "保存名:" & Right(phn, InStr(StrReverse(phn), "\") - 1)
    '保存の命令、phnはダイアログで入力したファイル名が入ってます
    ActiveWorkbook.SaveAs FileName:=(phn), FileFormat:=xlOpenXMLWorkbook

   <中略>

End Sub

因みに Unload UserForm1 の後にA1指定の命令を書いても結果は同じでした。
参照設定は追って確認します。

(ブリーフマスオAV) 2020/03/31(火) 16:23


シートオブジェクトを省略して、アクティブなシートを対象にいろいろやっていますね。 フォームコントロールのボタンのときからこのコーディングだったならば、シート切替に何か問題があったものと思われます。(今は標準モジュールのコードを無くしているようなので、推測しかできませんが)

現在は現象が出なくなったのは、ActiveXのボタンを使った事で、マクロがシートモジュールに書かれる事になり、シートを省略した場合はマクロを書いたシートが対象になる、という点が変化したためかと思われます。 シート省略した場合の動作が変わっているのですね。 コントロールを変えて直ったのはたまたまであり、悪いのはシートを省略したコーディングにしてしまったためでしょう。

今のマクロは正しく動作しているようならば、下手に変更しない方が良いでしょう。 今後は、Select主体のコーディングは止めて、シートオブジェクトを明示するようにしてみてください。

シートの省略の他に、On Error Resume Next をかけっぱなしにしている点も気に入りませんね。 コードに問題があってもそのまま動いてしまい、問題点に気付けなくなりますよ。 On Error は、それが必須でない場合は使うべきでは無いです。エラー箇所でマクロが止まってくれたほうが、間違えたまま先に進んでしまうより、被害が無いですよ。
(???) 2020/03/31(火) 16:54


もひとつだけ気になった点。 間違ってはいないのですが、
    Cells(2, 3) = "保存名:" & Right(phn, InStr(StrReverse(phn), "\") - 1)

InStrとStrReverseを組み合わせるより、InStrRev関数を使う方が良いと思います。 StrReverseって、入れ替え先のメモリ領域と、1文字ずつ全文字列を入れ替える時間がかかりそうですが、InStrRev なら入れ替える必要が無いですからね。 まぁ、気にするほどの差ではありませんが。

    Cells(2, 3) = "保存名:" & Mid(phn, InStrRev(phn, "\") + 1)
(???) 2020/03/31(火) 17:10

???さん、ありがとうございます。

とても分かりやすい説明でした。

シートオブジェクトの省略はあまりよろしくないと、どこかの文献で見たのですが、その時既にかなりの行数書いていた為スルーしておりました。
次回マクロを組む機会がある時には、シートもきちんと指定したコードを書くようにします。

On Error Resume Next を入れたのは「同じファイル名が存在するけど、上書きする?」で「いいえ」を選択した場合エラーになってマクロが止まってしまうので入れました。保存作業が終了したら解くようにします。

ありがとうございました。
(ブリーフマスオAV) 2020/04/01(水) 09:25


自己解決したのですが、今後同じ様な症状で悩んでいる方が出てくるかもしれないので書き込ませていただきます。

フォームコントロールからActiveXコントロールに変更してボタンが押せなくなるのは回避したのですが、新規でシートを保存する際に「マクロも保存するのかどうか?」というダイアログが一々表示されて、これでは使い物にならないので、結局フォームコントロールに戻しました。

フォームコントロールの時は標準モジュール内にマクロを記述していたので保存シートにはマクロの記述が無かったのに対し、ActiveXコントロールは該当シート内にマクロを記述することになるから、ダイアログが出るという理屈ですよね。

保存時の拡張子を*.xlsmにすれば行けるのかもしれませんが、今までのデータが使えなくなる恐れがあったので拡張子の変更は止めました。

で、「セルが選択できない」のは何故か調べようと、セルを選択した後に「Application.WAIT」で1秒だけ間を置いてみました。(ブレークポイントを設定すると処理が上手く行くので)
最初の書き込みに「処理をすっとばす」と書いてしまいましたが、実際はキチンと選択していました。しかしEnd Subまで来て処理が終わると、勝手に選択が解除されてしまうようでした。

理由はわかりません。

色々試してみて、「シート保存時にシート上にあるボタンは保存しない」様な処理をすると何故か上手く行きました。

Sheets("印刷").Copy
ActiveSheet.DrawingObjects.Delete ←この1行を追加
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs FileName:=(Path), FileFormat:=xlOpenXMLWorkbook
Application.DisplayAlerts = True
ActiveWorkbook.Close

どういう関係があるのかさっぱりですが、とりあえずこれでマクロ終了時に印刷シートのセルが選択され、ボタンが押せるようになりました。

因みに保存したシートからボタンが無くなっても、読込時はシートをそのまま貼り付けるのではなく、読み込んだシートからデータだけコピーペーストする仕様になっているので問題はありません。
(ブリーフマスオAV) 2020/04/06(月) 11:15


コメント返信:

[ 一覧(最新更新順) ]


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