- サマリ: マクロにおいて、calcの特殊フィルターの利用の仕方について
- 環境: Basic
- 状態: 未解決
- 投稿者: ponkan?
- 投稿日: 2008-04-06 (日) 21:25:21
質問 
マクロの記録で、calcの特殊フィルターの動作を記録しても
rem dispatcher.executeDispatch(document, ".uno:DataFilterSpecialFilter", "", 0, Array())
と記録されてうまく動作しません。remは削除したとして
条件フィルターの範囲はどの様に指定するのでしょうか?
因みに、条件はcalcの特定cell範囲に指定して有ります。
回答 
- dispatch でのオプションはソースコードを見ないと分かりそうにありません。普通にマクロで行う方法を書いておきます。
ヘルプの「フィルタ: 特殊フィルタを使う」ページの例で試してみました。
| A | B | C | D | E |
1 | 月 | 標準 | ビジネス | ハイクラス | スイート |
2 | 1月 | 125600 | 200500 | 240000 | 170000 |
3 | 2月 | 160000 | 180300 | 362000 | 220000 |
4 | 3月 | 170000 | 133354 | 400000 | 486444 |
フィルターの条件は "列A" = "1月" OR "列B" < 160000 です。
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
| | Sub SpecialFilter_1
oDoc = ThisComponent
oSheets = oDoc.getSheets()
oSheet = oSheets.getByIndex(0)
' データ範囲
oRange = oDoc.getSheets().getByIndex(0)._
getCellRangeByPosition(0, 0, 4, 3)
' get filter descriptor
oFD = oRange.createFilterDescriptor(True)
oFD.ContainsHeader = True ' ヘッダを含む
oFD.CopyOutputData = True ' 結果をコピー
oFD.IsCaseSensitive = False ' 大文字と小文字を区別
oFD.SkipDuplicates = False ' 重複を無視
oFD.SaveOutputPosition = True ' 保存先を記憶
oFD.UseRegularExpressions = False ' 正規表現を利用
' 表の向き
oFD.Orientation = com.sun.star.table.TableOrientation.ROWS
' 結果の出力開始セル位置
aPos = CreateUnoStruct( _
"com.sun.star.table.CellAddress" )
aPos.Sheet = 0
aPos.Row = 9
aPos.Column = 0
oFD.OutputPosition = aPos
nFilterConnection = com.sun.star.sheet.FilterConnection
nFilterOperator = com.sun.star.sheet.FilterOperator
Dim aFields(1) As New com.sun.star.sheet.TableFilterField
' 条件指定
' 条件 AND または OR
aFields(0).Connection = nFilterConnection.AND
' 判定列インデックス指定
aFields(0).Field = 0 ' 列 0
' 比較方法
aFields(0).Operator = nFilterOperator.EQUAL
' 数値として比較
aFields(0).IsNumeric = False
' 数値
aFields(0).NumericValue = 0.0
' 文字列
aFields(0).StringValue = "1月"
' 条件2
aFields(1).Connection = nFilterConnection.OR
aFields(1).Field = 1
aFields(1).Operator = nFilterOperator.LESS
aFields(1).IsNumeric = True
aFields(1).NumericValue = 160000.0
aFields(1).StringValue = ""
oFD.setFilterFields(aFields)
' フィルター実行
oRange.filter(oFD)
End Sub
|
- はにゃ?さんレス有難うです。--SpecialFilter", "", 0, Arrayの、""の間なんだと思うのですが・・試行錯誤して見ます。 -- ponkan
- 上のようなコードを吐き出すマクロを作成してみました。
spfilter.ods
でもフィルターはデータ数が増えたりすると範囲が変わるんですよね。するとマクロに範囲が入っていると…。
条件を保存しておいて、フィルタ実行時に範囲を選択させるようなものにすればいいのでしょうけれど。使いたい人が現れたら手直しすることにします。
一応、試し方。
- 上記ファイルを開きます。
- 実際にフィルタしたい表と同じ列ヘッダを持った表を作成します。このとき、データは必要ありません.
- 表の上に置いてあるボタンを押します。
- ダイアログが表示されるので、実際にフィルタしたいセル範囲を選択します。
- その他必要な項目やフィルタ設定を入力します。
- OK ボタンを押します。
- Writer ドキュメントが表示されてコードが書き込まれます。
- どこかのモジュールにコピーして使用してください。
- 忙しさに感けて、斜め読みに読み飛ばしておりましたが
はにゃさん、再度のレスを有難う御座います。
何気に、ソースを吐出してくれるマクロを貼って頂いてたようで
早速の所、美味しい所は頂くようにしたいと思います。
実際、このスレの為に書き下ろして頂いたものだとすれば
これは本当に感謝感激で、頭の下がる想いが致します。
重ねて御礼を申し上げます。
さて、要望があれば・・・云々との事ですので敢えて書いて見ます。
スレ冒頭にも書きましたが、重要だったのは
データ範囲の指定では無く、フィルター条件の範囲指定でした。
シートの特定部分に、ラベルを含んだ条件を書込みして有りますので
そのフィルター条件の範囲さえ指定すれば、結果が出るようにと
考えていたのです。
例えば
データ範囲のラベルの直下の行を、フィルター条件範囲と指定して
フィルターを実行し
その得られた結果の行を、必要な処理をして行ごとデータ範囲から削除し
フィルタを解除して、再度ラベル直下の行をフィルター条件とします。
以下繰り返し、データ範囲が空になるまで行います。
つまり、データ範囲は動的に減少するものだったと言う事でした。
特殊フィルタ自体はマクロ全体の一部分で、味噌だったのは上記の中の
必要な処理・・・という所でした。
ここまで書くと、諸兄の中には・・・データパイロットを使えよ
との指摘もあろうかとは思いますが。
そこが・・何と云うか。
嗚呼やっぱりDispatch、されどDispatchなのでした。
ponkanも五日目もやめて、ものぐさ太郎と改名しようと思う此の頃です
長文失礼しました。
感想,コメント,メモ 