web-dev-qa-db-ja.com

OfficeでActiveXオブジェクトのサイズが自動的に変更されるのを防ぐ方法は?

このスレッド は、ExcelスプレッドシートのActiveXオブジェクトで発生していた問題について説明しています。読み通すのはめちゃくちゃで、最終的にまとまりのある答えはありません。

問題は100%再現可能です。

  1. ドッキングステーションの使用中にスプレッドシートでActiveXオブジェクトを含むブックを開く
  2. ドッキングステーションからマシンを切断し、解像度の変更をトリガーします(他にも原因があります。私のものはドッキングステーションにあり、解像度の変更が原因のようです)
  3. ActiveXコントロールをクリックすると、すぐにサイズが変更され、フォントのサイズが変更されます。 fontsizeの変更は.Font.Sizeパラメータの関数ではありませんが、継続的にfontsizeを増やすこと以外は、問題が発生した後に変更できないものです。

信頼できると思われる唯一の解決策は、MSパッチ(数年前は「修正プログラム」だったため、完全な展開には実用的ではないように思われます)とレジストリの編集を含み、これは私の使用例では実用的ではありません。

私はどちらかの方法を探しています:

  1. この変更が発生しないようにする
  2. 最適な回避策を見つける

この問題に関する信頼できる情報がオンラインで不足しています。私は自分の仕事を投稿するつもりですが、理想に近いものではなく、より良い解決策を望んでいます。

14
enderland

私の回避策は、プログラムですべてのOLEオブジェクト上のシートを反復し*、デバッガーにコードを記述してから、基本的に「オブジェクトのサイズ変更」ボタンをシート上に含めることです-この問題の理由を説明します発生しています。

このメソッドは、そのボタンを駆動するコードを生成します。

ただし、自動的には更新されません。これはスナップショットであり、アプリの展開の直前にonlyを使用する必要があります(エンドユーザーがボタン機能を使用する場合)。

その後、シーケンスは次のようになります。

  1. 次の方法で生成されたコードを実行する
  2. すぐにブックを保存-フォントの変更が継続して発生するのを防ぐことはありません
  3. ブックを再度開くと問題は「解決」されます

Private Sub printAllActiveXSizeInformation()
    Dim myWS As Worksheet
    Dim OLEobj As OLEObject
    Dim obName As String
    Dim shName As String

    'you could easily set a for/each loop for all worksheets
    Set myWS = Sheet1

    shName = myWS.name

    Dim mFile As String
    mFile = "C:\Users\you\Desktop\ActiveXInfo.txt"


    Open mFile For Output As #1
    With myWS
        For Each OLEobj In myWS.OLEObjects
            obName = OLEobj.name

            Print #1, "'" + obName
            Print #1, shName + "." + obName + ".Left=" + CStr(OLEobj.Left)
            Print #1, shName + "." + obName + ".Width=" + CStr(OLEobj.Width)
            Print #1, shName + "." + obName + ".Height=" + CStr(OLEobj.Height)
            Print #1, shName + "." + obName + ".Top=" + CStr(OLEobj.Top)
            Print #1, "ActiveSheet.Shapes(""" + obName + """).ScaleHeight 1.25, msoFalse, msoScaleFromTopLeft"
            Print #1, "ActiveSheet.Shapes(""" + obName + """).ScaleHeight 0.8, msoFalse, msoScaleFromTopLeft"

        Next OLEobj
    End With

    Close #1

    Shell "NotePad " + mFile



End Sub

*注:残念ながらグループ化されているオブジェクトも見つかりません。

2
enderland

このモジュールは2011年3月20日のE-Eのdlmilleによって作成されました

これは、シートに基づいてワークシートにActive-Xコントロール設定を保存し、Excelが「風変わり」になり、形状サイズが斜めになる場合に設定を保持するための演習です。ListBoxにはIntegralHeightプロパティがあり、その副作用はFALSEです。設定は、そのコントロールが斜めにならないようにします。コマンドボタンには、セルを使用した移動/サイズなどのプロパティがありますが、他のコントロールはそれほど優雅ではありません。

ルーチンsetControlsOnSheet():1)アクティブシート上のすべてのOLEObject(active-x)コントロールについて6つの共通コントロール設定を取得し、2)これらの設定を文字列配列、sControlSettings()に格納し、3)追加/更新これらの設定で定義された名前(非表示)。

シート上の各コントロールの定義名は、アクティブなシート名とコントロール名(一意のインスタンスを作成する必要があります)に基づいて作成されます。

プロセス:ユーザーは、ワークシートに配置するコントロールを作成します。いつでも、setControlsOnSheet()ルーチンを実行して、最初にすべてのコントロールの設定を保存するか、それらの設定を更新するか、新しい設定を追加できます(シート上のすべてのコントロールに対してこれを行います)。

すべての設定が「正しく見える」ように注意する必要があります(たとえば、Excelはまだ「風変わり」になっていないか、ユーザーが自分のコントロールの1つを調整して、設定を「保存」する準備ができています。それ以外の場合は、サイズが不適切なコントロールの設定は保存されます。

このルーチンプロセスを集中的に行うのではなく、シートをアクティブにするためのThisWorkbookイベントは、選択されたばかりのシートに存在するすべてのコントロールのすべての設定を「再初期化」します。このようにして、シート上のコントロール設定は、最後に保存された設定に「復元」されます。つまり、「永久に?」 Excelの「風変わりな」サイズ変更の結果を回避します。

潜在的な機能強化として、このアプリをアドインの一部としてクラスモジュールに埋め込むことで、関連するコードをユーザーの「通常の」プログラミング環境から除外できます。たとえば、シートのアクティブ化イベントのトラップは、ユーザーがThisWorkbookモジュールに追加する必要がなく、クラスモジュールでキャプチャされます。

Const CONTROL_OPTIONS = "Height;Left;Locked;Placement;Top;Width" 'some potentially useful settings to store and sustain

Function refreshControlsOnSheet(sh As Object)'routine enumerates all objects on the worksheet (sh), determines which have stored settings, then refreshes those settings from storage (in the defined names arena)

Dim myControl As OLEObject
Dim sBuildControlName As String
Dim sControlSettings As Variant

For Each myControl In ActiveSheet.OLEObjects
    sBuildControlName = "_" & myControl.Name & "_Range" 'builds a range name based on the control name
    'test for existance of previously-saved settings
    On Error Resume Next
    sControlSettings = Evaluate(sBuildControlName) 'ActiveWorkbook.Names(sBuildControlName).RefersTo 'load the array of settings
    If Err.Number = 0 Then ' the settings for this control are in storage, so refresh settings for the control
        myControl.Height = sControlSettings(1)
        myControl.Left = sControlSettings(2)
        myControl.Locked = sControlSettings(3)
        myControl.Placement = sControlSettings(4)
        myControl.Top = sControlSettings(5)
        myControl.Width = sControlSettings(6)
    End If
    Err.Clear
    On Error GoTo 0
Next myControl      
End Function

Private Sub storeControlSettings(sControl As String)
Dim sBuildControlName As String
Dim sControlSettings(1 To 6) As Variant ' set to the number of control settings to be stored
Dim oControl As Variant

Set oControl = ActiveSheet.OLEObjects(sControl)

'store the settings to retain, so they can be reset on demand, thus avoiding Excel's resizing "problem"
'create array of settings to be stored, with order dictated by CONTROL_OPTIONS for consistency/documentation

sControlSettings(1) = oControl.Height
sControlSettings(2) = oControl.Left
sControlSettings(3) = oControl.Locked
sControlSettings(4) = oControl.Placement
sControlSettings(5) = oControl.Top
sControlSettings(6) = oControl.Width


sBuildControlName = "_" & sControl & "_Range" 'builds a range name based on the control name

Application.Names.Add Name:="'" & ActiveSheet.Name & "'!" & sBuildControlName, RefersTo:=sControlSettings, Visible:=False 'Adds the control's settings to the defined names area and hides the range name
End Sub


Public Sub setControlsOnSheet()
Dim myControl As OLEObject

If vbYes = MsgBox("If you click 'Yes' the settings for all controls on your active worksheet will be stored as they CURRENTLY exist. " & vbCrLf & vbCrLf _
                & "Are you sure you want to continue (any previous settings will be overwritten)?", vbYesNo, "Store Control Settings") Then

    For Each myControl In ActiveSheet.OLEObjects 'theoretically, one could manage settings for all controls of this type...
        storeControlSettings (myControl.Name)
    Next myControl

    MsgBox "Settings have have been stored", vbOKOnly
End If
Application.EnableEvents = True 'to ensure we're set to "fire" on worksheet changes
End Sub
1
Rui Honorio

唯一の100%信頼できる回避策は、Excel(非表示のインスタンスを含む)を閉じて再起動することです。その他の解決策には問題があります。

これが、可能な限りコントロールを回避する理由の1つです。例については here を参照してください。

1
stenci

私は@RuiHonoriが最善の答えだと思いますが、すべてのシートのコントロールを希望する場所に移動するために、たまたま同じサイズでしたが、これを使用しました:

Sub SizeControls()
    Dim myControl As OLEObject
    Dim WS As Worksheet
    For Each WS In ThisWorkbook.Worksheets
        For Each myControl In WS.OLEObjects
            myControl.Height = 42.75
            myControl.Width = 96
        Next myControl
    Next WS
End Sub
0
Steven Good

これは過去に私に起こっていました(PCへの遠隔接続を使用した後または使用中)が、Workbook_WindowActivateイベントを使用してコマンドボタンとそのフォントのサイズを変更する解決策を考え出しました(これは、 「設定をリセットする」ボタンもあると思います)。

とにかく、今日まで遠く離れた接続を使用し、2つのコマンドボタンが誤動作し始めるまで、すべてが修正されたと思いました。これら2つのコマンドボタンのPlacementプロパティは2(オブジェクトはセルと共に移動されます)に設定されていましたが、他のものは3(オブジェクトはフリーフローティング)に設定されていました。

しかし、これを見つける前に、ボタンのフォントサイズを(プロパティウィンドウを使用して)必要なものに設定しようとしましたが、ボタンの高さを変更するまで、Windowsは使用していた数字を無視していました...すべて突然、フォントサイズプロパティを読み取り、それに応じて調整しました。

配置プロパティが実際に問題の一部であるかどうかはわかりませんが、念のため、2つのソリューションを使用します。

(1)配置は3(2) Workbook_WindowActivateイベントでトリガーされる「自動サイズ変更」関数は、ボタンとフォントサイズを少し大きくしてから、本来のサイズに戻します。しかし、おそらくソリューション(1)で十分でしょう...私には今テストする時間はありません。これがWorkbook_Activateイベントのコードです。

Worksheets(1).Shapes("CommandButton1").Top = 0
Worksheets(1).Shapes("CommandButton1").Left = 206.25
Worksheets(1).Shapes("CommandButton1").Width = 75
Worksheets(1).OLEObjects(1).Object.Font.Size = 10
Worksheets(1).Shapes("CommandButton1").Height = 21
Worksheets(1).Shapes("CommandButton1").Height = 18.75
Worksheets(1).OLEObjects(1).Object.Font.Size = 8

これですべて正常に動作します。ネットで解決策を見つけるために、過去に少し時間を要しました。これが少なくとも1人の人の役に立つことを願っています;-)

0
Xeliax

同様の問題がコメントと形状にも存在します。回避策の1つは、マクロを記述して。Widthおよび。Heightプロパティと、未使用のワークシート上の各オブジェクトのシート位置プロパティを記録することです。次に、必要に応じてこれらのプロパティを再確立するための2番目のマクロを記述します。

0
Gary's Student

ボタンにいくつかの問題があり、フォントサイズはその1つです。ボタンのサイズ変更とボタン内の画像のサイズ変更も行いました。プログラムでボタンのサイズを元に戻すことはできましたが、画像のサイズをそのように変更する方法が見つかりませんでした。私はこれらの問題の究極の解決策が何であるかを見つけたと思います。

MSForms.exdファイルを(私の場合)C:\ Users {UserName}\AppData\Local\Temp\Excel8.0から削除した場合、画面解像度でボタンを表示したいので、 Excelを再起動すると、これらの問題は消えたようです。他のアプリケーションのために削除する必要がある他の.exdファイルがあります。それらのいくつかは:

C:\Users\[user.name]\AppData\Local\Temp\Excel8.0\MSForms.exd

C:\Users\[user.name]\AppData\Local\Temp\VBE\MSForms.exd

C:\Users\[user.name]\AppData\Local\Temp\Word8.0\MSForms.exd

PowerPointにも1つありますが、関連するサポートドキュメントを見つけることができません(覚えている限り、これらの特定の問題を実際に呼び出すことはありません)

0
tbaker818