Cells.Count & [ For Each セル範囲 ]

エクステンションの作成、共用ライブラリ
返信する
K.Tsunoda
記事: 71
登録日時: 11月 2, 2008, 6:44 pm
連絡する:

Cells.Count & [ For Each セル範囲 ]

投稿記事 by K.Tsunoda »

VBA での Cells.Count に当たるプロパティが見つからなかったので代替関数を作りました。
また、VBAでの[For Each セル範囲]が簡単には出来ませんので、セル範囲を単一セルオブジェクトの
配列に分解する関数も作りました。
単一セル(A1)・セル範囲(A1:B5)・セル範囲コンテナ(A1:B5;D3:F10)を意識せずに使えます。


『Cells.Count & [ For Each セル範囲 ] 』 ( Ver 1.4 , 2009/9/2 )
http://blog.livedoor.jp/addinbox/archives/51243120.html

コード: 全て選択

~~ 利用例 ~~
(7/24 分解セルを順にセレクトするコードを追加)
(7/25 ThisComponent以外のテストケースを追加)

Sub Main
Dim oDoc As Object
Dim oCells As Object
Dim oCellsItem() As Object
Dim oController As Object
Dim lngCount As Long
Dim i As Long
Dim strMsg As String
Dim strSheetName As String

  oDoc = ThisComponent
  'oDoc = GetComponent("無題 1",True)      '(注)
  
  oCells = oDoc.getCurrentSelection
  'oCells = oDoc.Sheets(1).getCellRangeByName("A5:C8")
  
  MsgBox GetCellsCount(oCells)
  
  lngCount = GetCellsItem(oCells, oCellsItem)

  strMsg = Join(Split(oCells.AbsoluteName,"$"),"") & chr(13) & "CellsCount=" & lngCount
  For i = 1 to lngCount
    strMsg = strMsg & chr(13) & Join(Split(oCellsItem(i).AbsoluteName,"$"),"")
  Next i
  MsgBox strMsg

  oController = oDoc.getCurrentController()
  With oCellsItem(1)
    strSheetName = .Spreadsheet.Name
    oController.setActiveSheet(.Spreadsheet)
  End With
  For i = 1 to lngCount
    MsgBox "Next Cell select"
    With oCellsItem(i)
      If (strSheetName <> .Spreadsheet.Name) Then
        strSheetName = .Spreadsheet.Name
        oController.setActiveSheet(.Spreadsheet)
      End If
    End With
    oController.select(oCellsItem(i))
  Next i
End Sub
(注) GetComponent 関数は 下記参照。
http://blog.livedoor.jp/addinbox/archives/51192547.html



AddinBox/VBAユーザーの為のOpenOffice.org 備忘録 『ユーザー定義関数の一覧
http://blog.livedoor.jp/addinbox/archives/51249421.html
最後に編集したユーザー K.Tsunoda [ 9月 2, 2009, 12:14 pm ], 累計 5 回
K.Tsunoda
記事: 71
登録日時: 11月 2, 2008, 6:44 pm
連絡する:

Re:Cells.Count & [ For Each セル範囲 ]バージョンアップ案内

投稿記事 by K.Tsunoda »

2009/7/24 - Ver 1.1 -
"ThisComponent" 以外のドキュメントオブジェクトが対象の場合、[A1:B5]ケースでセルオブジェクトを
正しく生成する為に、GetCellsItem に argDoc 引数を追加(シートオブジェクトから親のコンポーネント
オブジェクトを取得する方法が判らない為)。


2009/7/25 - Ver 1.2 -
ドキュメント指定が無くても ThisComponent 以外を処理できましたので
Ver 1.1 で GetCellsItem に追加した argDoc 引数を外します。
( .RangeAddress.Sheet に気を取られて [ oDoc.Sheets(.Sheet) ] としていましたが、
シートオブジェクトならば [ argCells.SpreadSheet ] で十分な事に気付きました )

コード: 全て選択

argDoc の引数チェックを削除

Case "ScCellRangeObj"      ' e.g. [A1:B5]
 ' argItem(i) = oDoc.Sheets(.Sheet).getCellByPosition(lngCol, lngRow)
       ↓
  argItem(i) = argCells.SpreadSheet.getCellByPosition(lngCol, lngRow)

Case "ScCellRangesObj"     ' e.g. [A1:B5;E1:F8;G20:J30]
 ' lngCount = lngCount + GetCellsItem(oCellsEnumeration.nextElement(), argItem, oDoc)
      ↓
  lngCount = lngCount + GetCellsItem(oCellsEnumeration.nextElement(), argItem)
NakataMaho
記事: 177
登録日時: 6月 13, 2008, 11:19 am

Re: Cells.Count & [ For Each セル範囲 ]

投稿記事 by NakataMaho »

K.Tsunodaさん、
プロジェクトリードの中田ともうします。技術的なコメントできなくて残念ですが、
大変興味を持っています。私も以前OOoのVBAのコードを触っていたことが有りますので。
OOoのVBAにご興味有れば、現在、Novellで働いておられる、VBAの開発をやっている
Noel Powerさんをご紹介いたします。どうかお気軽に。

またvba.openoffice.orgにもMLがあります。
http://vba.openoffice.org/servlets/Summ ... stName=dev
K.Tsunoda
記事: 71
登録日時: 11月 2, 2008, 6:44 pm
連絡する:

Re: Cells.Count & [ For Each セル範囲 ]

投稿記事 by K.Tsunoda »

中田さん、こんにちは。
> OOoのVBA
[Option VBASupport 1] で動くVBAのエミュレータモード(?)の事でしょうか。

OOo.Basic オンリーで移植を行なうのが主眼なので、
「VBAを、そのまま動かす」よりは「OOo.Basic では、どう代替する」に興味が湧いてますね。

「どうしても、これはOOo.Basicでは無理、VBAでなければ」という機能だけ、
1モジュールに集めて、[Option VBASupport 1]を付けて、VBA機能を使って共通関数化するという
方法も考えた事がありますが、関数インターフェースが整合しないだろうなと思ってます。

呼び出し側はSheetオブジェクト(UNO) で引数を渡して、受け取り側の関数では Worksheetオブジェクト(VBA)で
受け取ってなんていう造りでは駄目でしょうからね・・・・
かといって「名前」で引き継いだのでは無駄手間だし・・・・


ただ、「なんで、OOo には コレが無いんだ! アレさえ有れば・・・」という思いの毎日ではあります。
K.Tsunoda
記事: 71
登録日時: 11月 2, 2008, 6:44 pm
連絡する:

Re: Cells.Count & [ For Each セル範囲 ]

投稿記事 by K.Tsunoda »

あっ、でも、先日悩んだ問題

[ EqualUnoObjects(Sheet1, Sheet1)=False ]
http://user.services.openoffice.org/ja/ ... f=10&t=415

は、OOo.VBA では、どのように対処(実装)しているのか興味ありますね。

OOo 3.0.0 では、[Option VBASupport 1] を入れても、VBAコードでの
シートオブジェクト比較は False になりました(下記の末尾)。
http://blog.livedoor.jp/addinbox/archives/51244102.html

Novell の有償版 OOo なら、VBAエミュレートも強力で True になっているのでしょうか?
NakataMaho
記事: 177
登録日時: 6月 13, 2008, 11:19 am

Re: Cells.Count & [ For Each セル範囲 ]

投稿記事 by NakataMaho »

Novell版は無償です。
まあ前身のximianが、OOo側のコードを取り入れてくれるスピードが遅くて話にならない
ということから、はじめたものですから。パッケージ、ソースコードのダウンロードなどは
http://www.go-oo.org/download/
からどうぞ。本質的にはupstreamしたいのですけど、まあ手が足りてないというのが現状です。
Ubuntu, RedHatなどは、これがほぼそのままはいってます。
Thanks
NakataMaho
記事: 177
登録日時: 6月 13, 2008, 11:19 am

Re: Cells.Count & [ For Each セル範囲 ]

投稿記事 by NakataMaho »

あと、Noelに質問したいことがあれば私、しますよ。
これがないんだ、とここで言ってても愚痴にしかなりませんし。
とりあえず、maho@openoffice.orgにメールください。
色々ぼちぼちやってみませんか。
NakataMaho
記事: 177
登録日時: 6月 13, 2008, 11:19 am

Re: Cells.Count & [ For Each セル範囲 ]

投稿記事 by NakataMaho »

> [Option VBASupport 1] で動くVBAのエミュレータモード(?)の事でしょうか。
ああ、私が言っているのは、そこですね。
K.Tsunoda
記事: 71
登録日時: 11月 2, 2008, 6:44 pm
連絡する:

Re: Cells.Count & [ For Each セル範囲 ] バージョンアップ案内

投稿記事 by K.Tsunoda »

2009/8/17 - Ver 1.3 -
下記「行 & 列オブジェクト」への対応が抜けていたので追加しました
ScTableRowObj , ScTableColumnObj
ScTableRowsObj , ScTableColumnsObj
K.Tsunoda
記事: 71
登録日時: 11月 2, 2008, 6:44 pm
連絡する:

Re: Cells.Count & [ For Each セル範囲 ] バージョンアップ案内

投稿記事 by K.Tsunoda »

( 2009/9/2 Ver 1.4 )

GetCellsItem でセルの分割時に ThisComponent を使用していた為、
他ドキュメントのセル範囲を指定した場合に、正しく他ドキュメントのセルが
取得できなかった不具合を修正しました。

Ver 1.2 で直した筈の下記の修正が元に戻っていたみたいです(すみませんでした)。

NG : argItem(i) = ThisComponent.Sheets(.Sheet).getCellByPosition(lngCol, lngRow)
OK : argItem(i) = argCells.Spreadsheet.getCellByPosition(lngCol, lngRow)
返信する

“コードスニペット(便利な汎用コード)”に戻る