半角チルダ

ExcelVBA、その他。
覚え書きや、補足資料などのスクラップブック。
end-u(1037781)

■CustomListの限界

2008-04-07 21:30:00 | VBA Tips
(知っててもあまり役に立ちそうもない情報2:-)
CustomList...[ツール]-[オプション]-[ユーザー設定リスト]の事です。
ユーザーオリジナルなリストを作成し、並び替えや連続データを作成したりする時に使ったりします。

この、リスト1つあたりに登録できる件数(行数)は何件までか。
Excel の仕様および制限
ここには記載が無いようなので、以前、調べてみた事があります。


1行の文字数1文字の場合、1,000行登録できました。
  5文字×333行。
 10文字×181行。
 20文字× 95行。
100文字× 19行。

総文字数によって変動します。行ごとに『,』の区切り文字がありますので、それを含めて2,000文字までのようです。(Excel2000)

検証してみたい方は下記のようなコードで。


Private Sub test1()
  Const y As Long = 1000 '作成する漢字データの行数
  Const x As Long = 4  '1行あたりの文字数

  Dim v  As Variant
  Dim n  As Long

  On Error GoTo errHndlr
  Sheets.Add
  With Range("A1").Resize(y)
    'ユニークな漢字データをCHAR関数で設定

    .Formula = "=REPT(CHAR(ROW(A12321)+INT((ROW(A1)-1)/94)*162)," & x & ")"
    .Value = .Value
    'CustomList登録
    Application.AddCustomList ListArray:=.Cells
  End With
  With Application
    v = .GetCustomListContents(.CustomListCount)
    '登録したCustomList削除
    .DeleteCustomList ListNum:=.CustomListCount
    n = UBound(v)

    Range("B1").Resize(n) = .Transpose(v)
    Range("C1:D1").Value = Array("データ行数", "登録できた行数")
    Range("C2:D2").Value = Array(y, n)
  End With
errHndlr:
  With Err
    If .Number <> 0 Then MsgBox .Number & ":" & .Description
  End With

End Sub

(結果)


ちなみに[リストの項目]のリストボックスにも表示制限があり、こちらは254行まで。これはあくまで表示上の制限なので、実際に登録されている行数とは違います。

Private Sub test2()
  Const y As Long = 500
  Dim v  As Variant

  Dim n  As Long

  On Error GoTo errHndlr
  Sheets.Add
  With Range("A1").Resize(y)
    .Formula = "=TEXT(ROW(),""0000"")"
    .Resize(, 2).NumberFormat = "@"
    .Value = .Value
    Application.AddCustomList ListArray:=.Cells
  End With
  With Application
    v = .GetCustomListContents(.CustomListCount)
    '.DeleteCustomList ListNum:=.CustomListCount '後で手動削除必要

    n = UBound(v)
    Range("B1").Resize(n) = .Transpose(v)
    Range("C1:D1").Value = Array("データ行数", "登録できた行数")
    Range("C2:D2").Value = Array(y, n)
  End With
errHndlr:
  With Err
    If .Number <> 0 Then MsgBox .Number & ":" & .Description
  End With

End Sub

(400行登録されているが表示は254行)


余談ですが、表示上の制限は他にもあるようですね。
CollectionやDictionaryなどのObjectのItem数に関しても、[ローカルウィンドウ/ウォッチウィンドウ]の表示は256件まで?

Private Sub test3()
  Dim i As Long

  Dim c As Collection

  Set c = New Collection
  For i = 1 To 257
    c.Add i
  Next

  Stop 'ここでウォッチ
  Debug.Print c.Item(257)
  Set c = Nothing
End Sub






また、[ユーザー設定リスト]に登録できるリスト数は最大何件か?

...についてはあまり検証しないほうが良いようです。
1回試してみた時は1,700件くらいでしたが、[ユーザー設定リスト]はレジストリに保存されるので、レジストリサイズが影響してくるのではないでしょうか。
[XL2000] ユーザー設定リストを共有する方法

(2010.04.22追記)
>総文字数によって変動します。行ごとに『,』の区切り文字がありますので、それを含めて2,000文字までのようです。
正確には1,999文字まで ?
Comment
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

■隠しオブジェクト

2008-04-04 22:00:00 | VBA Tips
ワークシート上のテキストボックスやシェイプを削除する時、シェイプの種別ごとに削除したい場合はLoop処理で判定しながら削除しますが、種別関係なく削除したい場合は

ActiveSheet.DrawingObjects.Delete

とします。
この場合、Pictures や ChartObjects なども削除されます。
Pictures や Rectangles , Ovals , TextBoxes など、種別を指定して削除する事もできます。
(TextBoxes の場合は、Rectangles や Ovals に[テキストの追加]をしている場合も含まれるので注意が必要)

DrawingObjects や TextBoxes , Pictures...などは[隠しオブジェクト]であり、バージョン95以前との互換性を保持するために残っています。
Excel2000までのヘルプファイル VBAXL9.CHM には[隠しオブジェクト]についての記述がありますが、2002以降の VBAXL10.CHM には記述がないようです。

これもApplicationクラスの関数と一緒で、いつまでサポートされるかわかりません...便利なのですが。
例えば TextBoxes 一括削除の場合
ActiveSheet.TextBoxes.Delete
これはTextBoxがなくてもエラーにはなりません。
また、TextBoxの検索などで、HitしたTextBoxに画面遷移したい時など
ActiveSheet.Shapes(1).Select
では選択されるだけで画面遷移しませんが、
ActiveSheet.TextBoxes(1).Select

ActiveSheet.Shapes(1).DrawingObject.Select
などは画面遷移を伴います。
Shapeオブジェクトを扱う時、色々と振る舞いが違う場合があるので、知っておくとコーディングの幅が広がるかもしれません。

さて、そこで今日の実験は 『TextBoxesのFontプロパティの一括設定時の制限について』です。
(前フリ長くてすみません:笑)

Sub pre() 'サンプルシート作成
  Dim x As Long
  Dim y As Long
  Dim n As Long

  With Sheets.Add
    For x = 1 To 20 Step 2
      For y = 1 To 20 Step 2
        n = n + 1
        .Cells(y, x).Value = n
        With .Cells(y, x + 1)
          .Worksheet.TextBoxes.Add .Left, .Top, .Width, .Height
        End With
      Next
    Next
    .TextBoxes.Interior.ColorIndex = 15
  End With
End Sub

これで100個のTextBoxが作成されます。



Interiorプロパティなどの設定は一括でできるのですが、

Sub test1()
  On Error GoTo errHndlr
  With ActiveSheet.TextBoxes
    .Interior.ColorIndex = 20
    .Text = "A"
    .Border.ColorIndex = 3
    .Font.Size = 10 'エラー
  End With
errHndlr:
  If Err.Number <> 0 Then
    MsgBox Err.Number & vbLf & Err.Description
  End If
End Sub



Fontプロパティはエラーで設定できません。
どうも1度に設定できるのは70個までのようです。

Sub test2()
  Dim i As Long

  With ActiveSheet
    .Range("A1").Select
    For i = 1 To 70
      .TextBoxes(i).Select False
    Next
    Stop
    Application.DoubleClick
    Stop
    .TextBoxes(71).Select False
    Application.DoubleClick
  End With
End Sub



複数選択して、手動でやる場合はエラーメッセージが出るわけでもなく、プロパティウィンドウが開かないだけのようです。
(ぃや、知っててもあまり役に立ちそうもない情報ですね...orz)
Comment
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

■Application.DoubleClickメソッド

2008-04-02 23:20:00 | VBA Tips
この話が出てきたら、変り種ネタももうそろそろ品切れなのである(笑
ヘルプには[DoubleClick メソッド]が載っているが、実行してもセル編集状態にならない。
BeforeDoubleClickイベントも反応しないし、実装されていないのではないか、という話がありました。
で、いろいろ試していたら以下のような事みたいです。

まず実験シートを作成します。Sub pre() 実行。

Option Explicit

Sub pre()
  Dim ws As Worksheet

  Set ws = ActiveSheet
  With Sheets.Add
    .Range("A1").Formula = "=J10"
    .Range("A3").Formula = "=SUM(" & ws.Name & "!A1:A10)"
    .Buttons.Add(100, 10, 50, 20).OnAction = "try"
    .Ovals.Add 10, 50, 50, 50
  End With
  Set ws = Nothing
End Sub
'-------------------------------------------------
Sub try()
  Application.DoubleClick
End Sub

▼結果(新規シート追加、数式設定、ボタンとシェイプ追加、ボタンにマクロ登録)



できたシートで、セルA1、A3、シェイプをそれぞれ『選択』して、Sub try() を実行してみてください。
(ボタンに登録してますが、直接実行でも可)
Application.DoubleClickメソッドが実装されている事が確認できます。

つまり、ヘルプにある
>DoubleClick メソッドは、アクティブ セルをダブルクリックする操作に相当します。
とは、
『DoubleClick メソッドは、SelectしたObjectをダブルクリックする操作に相当します。
ただし、Cellsオブジェクトについては Application.[EditDirectlyInCell プロパティ]が False の時の操作に相当します』
...といったところでしょうか。
Application.EditDirectlyInCell = False とは[ツール]-[オプション]-[編集]タブの設定で「セル内で編集する」のチェックを外した状態です。


(DoubleClick メソッド実行時には、EditDirectlyInCellをFalseにする必要はありません)

ですので、DoubleClick メソッドでセル編集状態に、と期待すると肩透かしをくらってしまうのでしょうね。
ちなみに、ピボットテーブル内セルをダブルクリックした場合は EditDirectlyInCellがTrue/False でも一緒で、その操作に相当します。

余談ですが、EditDirectlyInCell = False 時のセルダブルクリックを[マクロの記録]録ってみると意外と面白いです。
そのセルの数式によって変化します。

Sub Macro1()
  '
  'A1="=同シート内セル"の場合
  Range("A1").Select
  Selection.DirectPrecedents.Select
  '
  'A1="=同ブック他シートA1セル"の場合
  Range("A1").Select
  Application.Goto Reference:="Sheet2!RC"
  '
  'A1="=閉じたブックのシートのA1セル"の場合
  Range("A1").Select
  Workbooks.Open Filename:="D:¥test¥test.xls"
  Application.Goto Reference:="Sheet1!RC"
End Sub
Comment
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする