この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:5
ページ更新者:ぼうず
更新日時:2026-06-11 07:10:02

タイトル: トップレベルのコントロールをコントロールに追加できません。
SEOタイトル: VBA トップレベル コントロール エラーの原因と対処

この記事の要点
  • VBA UserForm 編集時のエラー: 「トップレベルのコントロールをコントロールに追加できません」
  • 主因: 別の UserForm にコントロールをドラッグ(CommandButton / Label 等を別 Form 間で移動)
  • 対処1: コントロールを 切り取り → 貼り付けではなく新規作成する
  • 対処2: 一旦 UserForm を閉じて再オープン、IDE をリセット
  • 対処3: 実行時に動的追加するなら Me.Controls.Add を使う

エラーの全文

コンパイル エラー:
トップレベルのコントロールをコントロールに追加できません。

(英語版)
Cannot add a top-level control to a control.

VBA エディタ(VBE)で UserForm を編集中、または UserForm をロード時に発生します。フォーム上のコントロール(CommandButton、TextBox、Label、Frame など)の親子関係が不正になっていることを示します。

原因: どんな操作で出るか

操作状況
別の UserForm のコントロールをドラッグして持ち込む★ 最頻パターン
UserForm のコントロールを別 UserForm に「切り取り → 貼り付け」正常に貼れたように見えて壊れる
Frame / MultiPage のページ内コントロールを Form 直下にコピー親子関係が崩れる
コードで Set ctrl.Parent = Me のように親を直接書き換え不正な親変更
破損した .frm / .frx ファイルをインポートファイルレベルで壊れている
サードパーティ製 ActiveX コントロール(古い OCX)混在登録不整合

対処1: コントロールを新規作成する

別の UserForm にコントロールを持っていきたい場合、コピー&ペーストではなく、移動先 UserForm で新規にコントロールを配置し、プロパティをコピーしてください。

  1. 移動元 UserForm でコントロールを選択 → プロパティウィンドウで設定値をメモ(Name, Caption, Font, Size 等)
  2. 移動先 UserForm を開く
  3. ツールボックスから同じ種類のコントロールを新規にドラッグ配置
  4. メモしたプロパティを設定
  5. 必要ならイベントハンドラのコードもコピー

対処2: UserForm を閉じて再オープン / VBE 再起動

一時的な内部状態の不整合の場合は VBE を再起動するだけで直ります:

  1. Excel を保存して閉じる
  2. Excel を再起動 → VBE (Alt+F11) を開く
  3. 該当 UserForm をダブルクリックして再表示

それでも消えない場合は、ファイルを別形式に変換する手があります:

  1. UserForm を右クリック → 「ファイルのエクスポート」で .frm ファイルとして保存
  2. プロジェクトから UserForm を削除
  3. 再度「ファイルのインポート」でエクスポートしたファイルを取り込む

対処3: 親子関係を意識して動的追加 (Controls.Add)

「Form A のコントロールを Form B にコードで移したい」というシナリオなら、デザイン時にドラッグするのではなく、実行時に Controls.Add で動的に作るのが正解です:

' Form B 側
Private Sub UserForm_Initialize()
    Dim btn As MSForms.CommandButton
    Set btn = Me.Controls.Add("Forms.CommandButton.1", "btnRun", True)
    With btn
        .Caption = "実行"
        .Left = 10
        .Top = 10
        .Width = 80
        .Height = 24
    End With

    Dim txt As MSForms.TextBox
    Set txt = Me.Controls.Add("Forms.TextBox.1", "txtInput", True)
    txt.Left = 10
    txt.Top = 40
End Sub
ProgIDコントロール
Forms.CommandButton.1コマンドボタン
Forms.TextBox.1テキストボックス
Forms.Label.1ラベル
Forms.ComboBox.1コンボボックス
Forms.ListBox.1リストボックス
Forms.CheckBox.1チェックボックス
Forms.OptionButton.1オプションボタン
Forms.Frame.1フレーム
Forms.MultiPage.1マルチページ

動的追加コントロールにイベントを付ける場合は、クラスモジュールWithEvents を使います:

' クラスモジュール: ButtonHandler
Public WithEvents Btn As MSForms.CommandButton

Private Sub Btn_Click()
    MsgBox "Clicked: " & Btn.Name
End Sub
' UserForm
Dim handlers As Collection

Private Sub UserForm_Initialize()
    Set handlers = New Collection

    Dim i As Long
    For i = 1 To 3
        Dim b As MSForms.CommandButton
        Set b = Me.Controls.Add("Forms.CommandButton.1", "btn" & i, True)
        b.Caption = "Button " & i
        b.Top = (i - 1) * 30 + 10
        b.Left = 10

        Dim h As ButtonHandler
        Set h = New ButtonHandler
        Set h.Btn = b
        handlers.Add h    ' GC 防止
    Next
End Sub

対処4: Frame / MultiPage 内のコントロールを扱うとき

Frame や MultiPage はコンテナであり、その中のコントロールの親は Frame / MultiPage です。Form 直下に移動するときは:

' ❌ NG: ドラッグで Frame の外に出した瞬間に親が変わって壊れる場合あり
' ✅ 推奨: 元 Frame 上で新規作成 → プロパティコピーして配置

' どうしてもコードで移動するなら、新規作成して元を削除
Dim newBtn As MSForms.CommandButton
Set newBtn = Me.Controls.Add("Forms.CommandButton.1", "btnNew", True)
newBtn.Caption = Me.Frame1.btnOld.Caption
newBtn.Left = Me.Frame1.btnOld.Left + Me.Frame1.Left
newBtn.Top = Me.Frame1.btnOld.Top + Me.Frame1.Top
Me.Frame1.Controls.Remove "btnOld"

対処5: 破損 UserForm の復旧

上記すべてで治らない場合、UserForm ファイル自体が破損している可能性が高いです:

  1. VBE で UserForm を右クリック → エクスポート → .frm + .frx を保存
  2. テキストエディタで .frm を開き、コントロール定義部分を確認
  3. 不正なエントリ(Parent 指定がおかしいもの)を手動修正
  4. 再インポート
  5. それでも壊れている場合は、新規 UserForm を作って一からコントロールを配置(最も確実)

予防策

  • UserForm 間でコントロールをドラッグや切り貼りで移動しない
  • 共通の UI ならクラスモジュール化して再利用
  • 頻繁に変わる UI は実行時 Controls.Add で動的生成
  • ファイルは定期的にバックアップ(特にレイアウト変更前後)
  • 巨大な UserForm は機能ごとに分割、MultiPage で TabStrip 化
  • 古い OCX / ActiveX への依存を減らす(標準コントロールで完結)

関連エラー

メッセージ関連
「オブジェクトはこのフォームの子オブジェクトではありません」同じく親子関係エラー、Controls コレクションで指定名が存在しない
「型が一致しません (Type mismatch)」動的追加時に Set 漏れ・型違い
「コントロールにフォーカスを設定できません」Visible/Enabled が False のコントロールに SetFocus
「自動化エラー (Automation error)」OCX 登録崩れ、regsvr32 で再登録要

FAQ

Q: 同じファイル / 同じ UserForm を編集中にいきなり出るようになった
A: Excel / VBE のメモリリーク状態のことがあります。一度保存して Excel を完全終了 → 再起動で消えることが多いです。

Q: 共有環境(OneDrive / Teams)で発生
A: 同時編集や非同期同期でファイル破損が起きやすい。ローカルで作業 → 完成版だけ共有が安全。

Q: Controls.Add で作ったボタンが UserForm を閉じてもメモリに残る
A: イベントハンドラ用のクラスインスタンスを Set h = Nothing で明示解放、または UserForm_Terminate で Set handlers = Nothing