[[20200903093712]] 『オートメーションエラーが発生します』(みらい) ページの最後に飛ぶ

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

 

『オートメーションエラーが発生します』(みらい)

エクセルVBA オートメーションエラーが発生します

Private Sub UserForm_Initialize()

Dim ws As Worksheet
Dim wsdata As Worksheet

Set ws = Worksheets("DataBase")

Set wsdata = Worksheets("データ用")

'IDにカーソルを合わせる

MultiPage1.Value = 表面

Me.txID.SetFocus

'新規登録の生年月日を入力日に設定

If tx記和暦 = "" And tx記年 = "" And tx記月 = "" And tx記日 = "" Then

tx記和暦 = wsdata.Range("A5")

tx記年 = wsdata.Range("B5")

tx記月 = wsdata.Range("C5")

tx記日 = wsdata.Range("D5")

End If

'表面裏面の処理

'必ず最初開いたときは表面にする

If MultiPage1.Value = 0 Then

Me.cmdch表面.BackColor = &H8080FF

Me.cmdch裏面.BackColor = &H8000000F

ElseIf MultiPage1.Value = 1 Then

Me.cmdch裏面.BackColor = &H8080FF

Me.cmdch表面.BackColor = &H8000000F

Else

End If

'ComBoxの管理

Me.tx記和暦.RowSource = "年号"

Me.tx記月.RowSource = "月"

Me.tx記日.RowSource = "日"

Me.tx生和暦.RowSource = "年号"

Me.tx生月.RowSource = "月"

Me.tx生日.RowSource = "日"

Me.txsex.RowSource = "性別"

Me.tx始和暦.RowSource = "入和暦"

Me.tx始月.RowSource = "月"

Me.tx始日.RowSource = "日"

Me.tx終和暦.RowSource = "入和暦"

Me.tx終月.RowSource = "月"

Me.tx終日.RowSource = "日"

Me.txaaaaa.RowSource = "xxの有無"

Me.txbbbbb.RowSource = "xxの有無"

Me.txcccccRowSource = "xxの有無"

Me.txddddd.RowSource = "xxの有無"

Me.txKKKK最終交換日和暦.RowSource = "入院和暦"

Me.txKKKK最終交換日月.RowSource = "月"

Me.txKKKK最終交換日日.RowSource = "日"

Me.txHHHHH増設日和暦.RowSource = "年号"

Me.txHHHHH増設日月.RowSource = "月"

Me.txHHHHH増設日日.RowSource = "日"

Me.txHHHHH最終交換日和暦.RowSource = "入院和暦"

Me.txHHHHH最終交換日月.RowSource = "月"

Me.txHHHHH最終交換日日.RowSource = "日"

Me.txEEEEEE和暦.RowSource = "年号"

Me.txEEEEEE月.RowSource = "月"

Me.txEEEEEE日.RowSource = "日"

tx棟.RowSource = "棟"

tx役職.RowSource = "役職"

'非表示化

Call ○○非表示

Call ○○非表示

Call ○○非表示

Call ○○非表示

Call ○○非表示

Call ○○非表示

Call ○○非表示

Call ○○非表示

Call ○○非表示

Call ○○非表示

Call ○○非表示

Call ○○非表示

'行番号ラベルに最終行+1をセット

If ws.Range("B4") = "" Then

Me.lb行番号.Caption = "1"

ElseIf Not wsdata.Range("Q8") = "" Then

Call DspDataSet(wsdata.Range("Q8"))

Else

Me.lb行番号.Caption = ws.Range("A4").CurrentRegion(ws.Range("A4").CurrentRegion.Count).Row - 2

End If

'選択を空欄にする

wsdata.Range("Q8") = ""

End Sub

〇〇非表示はそれぞれ 下記のように開いたフォームにあるオブジェクトを非表示にするマクロになっています

Sub 〇〇非表示()

lbXXXX.Visible = False

txXXX.Visible = False

End Sub

※一部文章を書き換えています

私が使っているPC メモリ 8GBのPCでは動作するのですが別の方のPC(メモリも型式もまちまち)だとオートメーションエラー(例外)が発生しエクセルが強制終了してしまいます

このフォームを
xxxxx.showで開くときに発生するエラーです

これが続いてしまうとさすがに支障をきたすのでオートメーションエラーの原因を取り払いたいです

ご教授いただけると幸いです よろしくお願いいたします。

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


 もうオートメーションエラーに関しては、検索されて概要は調べていると思いますが、
 原因の多くはコードの不具合ではなく、メモリ不足などの外的要因のことが多いようです。
 (こんなあたり?)
https://www.sejuku.net/blog/75643

 再現性の高いPCでタスクマネージャーを表示して、エクセルのメモリを確認しながらステップ実行してみて
 落ちる処理を特定できないでしょうか。

 Database や データ用 シートはどのくらいの行数で、数式などはどの程度使用されているでしょうか。
 不要なデータや数式の削除で、ファイルを軽くすることも有効かもしれません。
(QS) 2020/09/03(木) 09:57

データベースについては計算式はなく、データ用についても日付の自動計算以外は数式はほぼ使っていません
VBA内で大体の計算を補って、データベースシートにその結果を貼り付けする
データベースには別のフォームからアクセスすると印刷ができるようになっており、決まったフォーマットで顧客情報の印刷ができるようになっています

やはりメモリでしょうか
別部署PCは4gb目盛りなのでそれが原因なのかなぁとはにらんでおりますが

(みらい) 2020/09/03(木) 10:09


やったことはないのですが、
ComboBoxにデータを全てセットしているので、
イベントで触ったときのみ、データセットするように
してみたらいかがでしょうか。
(tkit) 2020/09/03(木) 10:21

なるほど試してみます
(みらい) 2020/09/03(木) 10:27

メモリーが足りない場合はどの部分を削ればよいのでしょうか
正直今のものからそんなに削れないと思うのですが、かといって今作ってるものが操作不安定だと厳しいので困っています
(みらい) 2020/09/03(木) 10:42

tkitさんへ これのやり方ですがちょっと自分では思いつかなかったのでご指南いただけないでしょうか
(みらい) 2020/09/03(木) 11:39

 >フォームにあるオブジェクトを非表示にするマクロになっています 
 プロパティウィンドウで Visible を False に設定にしておけば
 Call ○○非表示と Sub 〇〇非表示() は必要ありません。
 そのオブシェクトを表示するときのみ lbXXXX.Visible = True とすればよいのでは?
(APP) 2020/09/03(木) 12:30

ARPさん
プロパティウインドにするだけで動作は改善するものなのでしょうか?
そうするとComboBoxのデータセットもそちらにしたほうが良いのでしょうか
(みらい) 2020/09/03(木) 13:28

Excel2013以降、Excel内部の作りが大幅に変わったせいか(内部というか、おそらく全部作り直している)、コントロールが非表示の状態で利用すると、エラーになるようになったので、このせいかも知れません。

遅くなって処理時間が延びてしまいますが、シートやコントロールを非表示にする箇所を全てコメントアウトし、表示したまま動作するコードに変えて動かしてみてください。 表示したままなら正常動作するようであれば、「MSのバカヤロー!」と叫んでおしまいです。(修正される事を望めない)
(???) 2020/09/03(木) 13:46


表示をしたままでもエラー出ました

(みらい) 2020/09/03(木) 13:57


非表示関係なしでしたか。

次に怪しいと思うのは、UserForm_Initialize時にいろいろやりすぎているように見える点。 このプロシジャを抜けるまで、UserFormは表示完了していないので、上に乗っている部品は触らないほうが良いのです。 具体的には、代入処理関係を全て別プロシジャに分けて、OnTimeを使って(起動時間はNow()でOK)起動するようにすると、UserFormが表示完了してから、分けた分の処理を行うようになります。

これでうまくいくなら、別プロシジャから少しずつ(半分ずつとか)元に戻してみて、再発するかどうかを確認しつつ、どの辺りで問題発生するか切り分けてみてください。
(???) 2020/09/03(木) 14:08


???さんへ
とりあえず返信が来る前にやりすぎていると思われる動作(Rowsource系)をプロパティに入れてみたのですが、これ処理が軽くなることはありますかね?
これでいま試しますがダメなら???さんのアイディアを使ってみようと思います
(みらい) 2020/09/03(木) 14:13

プロパティを予めセットできるものはしておく、というのは、多少は効果あると思いますよ。 インタプリンタなので。(ただ、そこがエラー原因とは思いにくいです)

DspDataSetの中身が判らないですが、おそらくコンボ内容セットですよね? 例えば、これを呼ばなくともコンボが空になるだけなら、中身セットは後回しにしても良さそうです。
(???) 2020/09/03(木) 15:10


 >tkitさんへ これのやり方ですがちょっと自分では思いつかなかったのでご指南いただけないでしょうか

 興味が湧いたので書いてみました。
 新規Bookに新規のUserFormと ComboBox2つ、TextBox2つを作り、
 UserFormモジュールに以下のコードを張り付けてください。
 シート名Sheet1のA列B列の1行目から適当な値を数個セルに入力して
 試してみてください。
 あくまで実験用ですので、組み込む際には質問者さん自身でお願いします。

 Option Explicit
 Private IsAdd1 As Boolean
 Private IsAdd2 As Boolean

 Private Sub ComboBox1_DropButtonClick()
         Dim temp
     If IsAdd1 = True Then Exit Sub
     With ThisWorkbook.Worksheets("Sheet1")
         temp = .Range("A1", .Cells(Rows.Count, "A").End(xlUp)).Value
     End With
     ComboBox1.List = temp
     TextBox1.Value = ComboBox1.ListCount
     IsAdd1 = True
     Erase temp
 End Sub

 Private Sub ComboBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
     Dim buf
     With ComboBox1
         buf = .Value
         .Clear
         .Value = buf
     End With
     IsAdd1 = False
     TextBox1.Value = ComboBox1.ListCount
 End Sub

 Private Sub ComboBox2_DropButtonClick()
     Dim temp
     If IsAdd2 = True Then Exit Sub
     With ThisWorkbook.Worksheets("Sheet1")
         temp = .Range("B1", .Cells(Rows.Count, "B").End(xlUp)).Value
     End With
     With ComboBox2
         .List = temp
     End With
     TextBox2.Value = ComboBox2.ListCount
     Erase temp
 End Sub

 Private Sub ComboBox2_Exit(ByVal Cancel As MSForms.ReturnBoolean)
     Dim buf
     With ComboBox2
         buf = .Value
         .Clear
         .Value = buf
     End With
     IsAdd1 = False
     TextBox2.Value = ComboBox2.ListCount
 End Sub

(tkit) 2020/09/03(木) 15:19


どの行でエラーになりますか?
または、1行づつステップ実行してもエラーになりますか?

(tkit) 2020/09/03(木) 15:34


???さん DspDataSetの中身が判らないですが、おそらくコンボ内容セットですよね? 例えば、これを呼ばなくともコンボが空になるだけなら、中身セットは後回しにしても良さそうです。 DspDataSetは別のフォームから行番号を指定して開いたときにその行番号に対応したデータをすべてフォームのテキストボックスへ挿入する処理になっています

tkitさん ステップでやると普通に動きます
なのでどこでエラーといわれてもわからないと言ところです
ただRowsourceを消して起動したときはエラーは起きてないです
さらに別のフォームをあらかじめ開いた後質問のフォームを開くとエラーが起きないという現象もおきています

また、Rowsourceと非表示を削減してみたのですがまたエラーが出てしまいました

(みらい) 2020/09/03(木) 15:48


私なら、以下のようにFormモジュールにFunctionプロシージャを
用意します。
UserForm.Showで呼び出しているのを、Call UserForm.sampleで
呼び出してください。
これで一旦、Initialize後に処理が走るようになりますので。

ちなみに引数も渡せますし、便利ですよ。

 Function sample()
     Load Me
     '※現在のUserForm_Initialize処理
     Me.Show
     Unload Me
 End Function
(tkit) 2020/09/03(木) 15:59

ありがとうございます 
とりあえず今日明日皆様の意見を参考にしつつこのエラーに対応してみます!
(みらい) 2020/09/03(木) 16:12

 >私が使っているPC メモリ 8GBのPCでは動作するのですが
 そうとは思えません。このコードはエクセルから貼り付けたのですか。
 それとも手書きで記述したのですか。

 以下コードを拝見して気が付いた点を列記しておきます。
 ・『新規登録の生年月日を入力日に設定』ではワークシートを指定しているのに
   『ComBoxの管理』ではワークシートを指定しないのは何故ですか。
    Worksheets("DataBase") 、 Worksheets("DataBase") のどちらなんでしょうか。
 ・『新規登録の生年月日を入力日に設定』と『ComBoxの管理』に【tx記年、tx記日】
   の同一オブジェクト名があります。
   既にあるオブジェクト名と同じ名前は使用できないことになっています。
 ・tx◯◯◯はテキストボックスということですか。
 ・cmdch◯◯◯はコンボボックスということですか。
 ・『新規登録の生年月日を入力日に設定』と『ComBoxの管理』のtx◯◯◯は同一ですか。

 もう一度コードを見直してください。改善する余地があると思いますよ。
 コンボボックスに表示するデーターがどうなっているか興味が湧きました。

 >プロパティウインドにするだけで動作は改善するものなのでしょうか?
 オブジェクトの分だけステートメントを書かなくて済む。
 その分動作は早くなるそうです。

(APP) 2020/09/03(木) 22:17


おはようございます
APPさん  このコードでフォームは自分の動作環境では動いています
 >>・『新規登録の生年月日を入力日に設定』ではワークシートを指定しているのに
 >>『ComBoxの管理』ではワークシートを指定しないのは何故ですか。
  コンボボックスについてはプロパティに入れました
  コンボボックスの中身については名前の管理を使っているので特にワークシート指定をしてません
  >>Worksheets("DataBase") 、 Worksheets("DataBase") のどちらなんでしょうか。
   どういうことですか?
 >>・『新規登録の生年月日を入力日に設定』と『ComBoxの管理』に【tx記年、tx記日】
   の同一オブジェクト名があります。
   既にあるオブジェクト名と同じ名前は使用できないことになっています。
   コンボボックスはすべてプロパティにいれましたが、これについては同一ではなくこちらに挙げるときに一部コードの記載情報を消しているためそのようにみえるようになっているだけです
もうしわけありません
  
 >>・tx◯◯◯はテキストボックスということですか。
そうです
 >>・cmdch◯◯◯はコンボボックスということですか。
そうです
 >>・『新規登録の生年月日を入力日に設定』と『ComBoxの管理』のtx◯◯◯は同一すか。
違います
(みらい) 2020/09/04(金) 10:44

 >temp = .Range("A1", .Cells(Rows.Count, "A").End(xlUp)).Value

 どれだけの量で、どんな風になているのか解らないけど、直接ComboBox1.Listに入れた方が良いんでない。
(Why) 2020/09/04(金) 11:52

 >どういうことですか?
 間違っていました。
 Worksheets("DataBase") 、 Worksheets("データ用") でした。
 そうですか。あなたのPCでは動作しているんですね。
 >そのようにみえるようになっているだけで
 そのように見えたので回答したまでです。
 コードは省略しない方がいいです。
 今回のように誤解を招きますから。
(APP) 2020/09/03(木) 22:17はスルーしてください。

(APP) 2020/09/04(金) 12:20


おはようございます
こちらのVBAですがここまで省略してます

Private Sub UserForm_Initialize()
Dim ws As Worksheet
Dim wsdata As Worksheet
Set ws = Worksheets("DataBase")
Set wsdata = Worksheets("データ用")

'IDにカーソルを合わせる
MultiPage1.Value = 表面
Me.txID.SetFocus

'新規登録の生年月日を入力日に設定
If tx記和暦 = "" And tx記年 = "" And tx記月 = "" And tx記日 = "" Then

tx記和暦 = wsdata.Range("A5")
tx記年 = wsdata.Range("B5")
tx記月 = wsdata.Range("C5")
tx記日 = wsdata.Range("D5")

End If

'表面裏面の処理
'必ず最初開いたときは表面にする
If MultiPage1.Value = 0 Then
Me.cmdch表面.BackColor = &H8080FF
Me.cmdch裏面.BackColor = &H8000000F
ElseIf MultiPage1.Value = 1 Then
Me.cmdch裏面.BackColor = &H8080FF
Me.cmdch表面.BackColor = &H8000000F
Else
End If

'行番号ラベルに最終行+1をセット
If ws.Range("B4") = "" Then
Me.lb行番号.Caption = "1"
ElseIf Not wsdata.Range("Q8") = "" Then
Call DspDataSet(wsdata.Range("Q8"))
Else
Me.lb行番号.Caption = ws.Range("A4").CurrentRegion(ws.Range("A4").CurrentRegion.Count).Row - 2
End If
'選択を空欄にする
wsdata.Range("Q8") = ""
End Sub

DspDataSetには行番号を飛ばすことによって該当行のデータをボタンやテキストボックスへセットするというVBAとしています

そしてここまで省略してもメモリ4gbのPCではまだオートメーションエラーが発生し続けています
ただ、このフォームを開く前にVBAを空白1文字でも追加編集するか、別のフォームを起動するとオートメーションエラーが発生しなくなり、動作が正常になります
正直お手上げ状態です

(みらい) 2020/09/07(月) 08:43


If MultiPage1.Value = 0 Then
Me.cmdch表面.BackColor = &H8080FF
Me.cmdch裏面.BackColor = &H8000000F
ElseIf MultiPage1.Value = 1 Then
Me.cmdch裏面.BackColor = &H8080FF
Me.cmdch表面.BackColor = &H8000000F
Else
End If

の部分を消したらとりあえずエラーが起きなくなりました
この処理はフォームを開いたらボタンの色を赤くするという処理です
これを最初からボタンの色を赤色に設定しておいて、かつ裏面で開くことはフォームを開いたときに上の方のコードで絶対に無いように表面を指定しているのでこれでいいのかなとおもいました
これでオートメーションエラーにならなくなれば良いのですが
(みらい) 2020/09/07(月) 08:58


 元々、Initializeイベントで実行する処理が重すぎるのでは?
 が問題だと思っていたのですが・・・
 UserForm_Initializeプロシージャを消して、掲示されたエラーが
 出るコードを元に書いた以下のFunctionプロシージャを張り付けてもらい、
 [該当UserForm.Show]で開いていたコードを[Call 該当UserForm.InitializeTest]に
 書き換えて試してもらえませんか。

 Load Me で非表示状態で該当UserFormが読み出され、Me.Show で表示します。

 Function InitializeTest()
     Dim ws As Worksheet
     Dim wsdata As Worksheet

     Load Me
     '▲Initializeイベント済み

     Set ws = Worksheets("DataBase")
     Set wsdata = Worksheets("データ用")
     'IDにカーソルを合わせる
     MultiPage1.Value = 表面
     Me.txID.SetFocus
     '新規登録の生年月日を入力日に設定
     If tx記和暦 = "" And tx記年 = "" And tx記月 = "" And tx記日 = "" Then
         tx記和暦 = wsdata.Range("A5")
         tx記年 = wsdata.Range("B5")
         tx記月 = wsdata.Range("C5")
         tx記日 = wsdata.Range("D5")
     End If
     '表面裏面の処理
     '必ず最初開いたときは表面にする
     If MultiPage1.Value = 0 Then
         Me.cmdch表面.BackColor = &H8080FF
         Me.cmdch裏面.BackColor = &H8000000F
     ElseIf MultiPage1.Value = 1 Then
         Me.cmdch裏面.BackColor = &H8080FF
         Me.cmdch表面.BackColor = &H8000000F
     Else
     End If
     '行番号ラベルに最終行+1をセット
     If ws.Range("B4") = "" Then
         Me.lb行番号.Caption = "1"
     ElseIf Not wsdata.Range("Q8") = "" Then
         Call DspDataSet(wsdata.Range("Q8"))
     Else
         Me.lb行番号.Caption = ws.Range("A4").CurrentRegion(ws.Range("A4").CurrentRegion.Count).Row - 2
     End If
     '選択を空欄にする
     wsdata.Range("Q8") = ""
     Me.Show
 End Function

(tkit) 2020/09/07(月) 10:00


tkitさん
そちらのコードで試したところ
オートメーションエラーすらでずにエクセルがおちるようになりました
ですが
     '表面裏面の処理
     '必ず最初開いたときは表面にする
     If MultiPage1.Value = 0 Then
         Me.cmdch表面.BackColor = &H8080FF
         Me.cmdch裏面.BackColor = &H8000000F
     ElseIf MultiPage1.Value = 1 Then
         Me.cmdch裏面.BackColor = &H8080FF
         Me.cmdch表面.BackColor = &H8000000F
     Else
     End If
を消すと通常通りフォームが起動します
やはりこの部分が悪さをしてると思われます
(みらい) 2020/09/07(月) 11:39

コード上、ComboBoxのBackColorで処理が重くなっている
ということになります。

質問者さんのUserFormの配置やデータ関係等が分かりませんので、
現状私が試そうと思うのは、
ComboBoxを全て空の状態で表示が大丈夫であれば、
1つづつデータ入れていき、それでだめであれば、
(tkit) 2020/09/03(木) 15:19
を基に、使用前にデータを入れるようにします。

(tkit) 2020/09/07(月) 14:21


 MultiPage1 の Page2 には同一名のオブシェクトは設定できないはずだが?
『Name プロパティを設定できません』のメッセージがでたはず。
 >質問者さんのUserFormの配置やデータ関係等が分かりませんので
 同感です。そして何だかコードに怪しいところが見受けられます。
 メモリーだけてはなく相手方のパソコン環境はとうなっているのでしょうね。

(もも) 2020/09/07(月) 22:17


みなさまありがとうございます
最終的にこちらのコードまで削減してエラーがとりあえず出なくはなっています
ボタンの色を変える処理がオートメーションエラーの原因だったのかもしれません

Private Sub UserForm_Initialize()
Dim ws As Worksheet
Dim wsdata As Worksheet
Set ws = Worksheets("DataBase")
Set wsdata = Worksheets("データ用")

'IDにカーソルを合わせる
MultiPage1.Value = 表面
Me.txID.SetFocus

'新規登録の生年月日を入力日に設定
If tx記和暦 = "" And tx記年 = "" And tx記月 = "" And tx記日 = "" Then

tx記和暦 = wsdata.Range("A5")
tx記年 = wsdata.Range("B5")
tx記月 = wsdata.Range("C5")
tx記日 = wsdata.Range("D5")

End If

'行番号ラベルに最終行+1をセット
If ws.Range("B4") = "" Then
Me.lb行番号.Caption = "1"
ElseIf Not wsdata.Range("Q8") = "" Then
Call DspDataSet(wsdata.Range("Q8"))
Else
Me.lb行番号.Caption = ws.Range("A4").CurrentRegion(ws.Range("A4").CurrentRegion.Count).Row - 2
End If
'選択を空欄にする
wsdata.Range("Q8") = ""
End Sub
(みらい) 2020/09/09(水) 13:47


 >ボタンの色を変える処理がオートメーションエラーの原因だったのかもしれません 
 だったら MultiPage1.Value = 表面  は不要では?
(もも) 2020/09/09(水) 16:15

>>ももさん
確かに不要ですね
消してみました
これでエラーが発生しなければよいですが・・・
(みらい) 2020/09/10(木) 08:41

該当のUserFormModuleが壊れていて、
オートメーションエラーとなる場合もあるそうです。

一旦解放して、作り直せば案外解決したりして。
(tkit) 2020/09/10(木) 16:07


UserForm_InitializeでUserForm上のObjectの値を
いじっていますが、該当のObjectのChangeイベントを
使っていませんか?

内容によっては、永久ループする可能性がありますけど。

質問者さんが、どこまで求めているのか分かりませんが、
UserForm_Initializeのコードだけでは分からないことが
多いので、私では、もうお力になれないかと思いますので、
これにて失礼いたします。
(tkit) 2020/09/10(木) 16:57


コメント返信:

[ 一覧(最新更新順) ]


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