マクロの画面更新の停止 †
ページ | OpenOffice.org FAQの登録ページ |
---|---|
投稿者 | 匿名 |
分類 | |
優先順位 | |
状態 | |
カテゴリー | |
投稿日 | 2009-10-31 08:56:33 (土) |
OS | Windows XP |
依存するページ | |
バージョン |
メッセージ †
回答ページでは行末に「~」を付加する必要はありません |
Excelの画面更新の停止は『Application.ScreenUpdating = False』で行えます。
OOo Basicでは『ThisComponent.LockControllers()』や『ThisComponent.addActionLock()』で停止できるとの記述を見かけましたが、うまくいきません。
Excelで作成していたマクロをなんとか移行したのですが、画面は動くは動作は非常に遅いはで困っています。
どこにどのように記述すれば良いか教えていただきたいです。
初歩的なことで申し訳ないのですが、よろしくお願いします。
OOo はドキュメント単位 †
K.Tsunoda (2009-10-31 13:45:26 (土))
Excel/VBA では Application.〜 ですから、Excel全体に作用します。
OOo.Basic では ThisComponent.〜 ですから、ドキュメント単位で機能します。
例えば、A.ods 内のマクロから B.ods を更新する際に
ThisComponent.LockControllers と記述していたら機能しません。この場合、
(B.odsのドキュメントオブジェクト).LockControllers と書く必要があります。
この辺りを確認してみてください。
ありがとうございます †
匿名 (2009-10-31 16:57:12 (土))
同じファイル内でのマクロになりますのでThisComponent.addActionLock()で問題ないかと思っています。(よくわからないので両方記述しています。)がうまく行きません。
なにか根本的に間違っているのでしょうか??
ちなみにVBA Supportを用いていてVBAの記述とOOoのBasicの両方の記述があります。
VBASupport 1 も中身は同じ †
K.Tsunoda (2009-10-31 17:26:30 (土))
VBASupport 1 配下での[Application.ScreenUpdating]を実行する
OOo のソースを閲覧してみましたが、行なっている事は
カレントドキュメントに対する LockControllers/UnlockControllers です。
> 画面は動くは動作は非常に遅いは
処理はセルへの書き出しでしょうか?
更新対象のオブジェクトによって効き目が違うのかもしれませんが、
少なくともセル書き出しには効果ある筈です。
そうですか… †
匿名 (2009-10-31 17:35:20 (土))
セルへの書き出しがよく理解出来ていないのですが…条件にあうものを選択して別シートに貼り付ける作業を行っています。
単に画面のちらつき(更新)を抑えたいのですが、それには難しいのでしょうか?
マクロにもよる †
K.Tsunoda (2009-10-31 18:21:49 (土))
例えば、「マクロの記録」を元にした下記のような Select 使いまくりなマクロの場合
Excel では ScreenUpdating の効果はありますが、
OOo では、ある程度まとまった回数分の
画面更新が止まったり進んだりと面白い動きをします。
Option VBASupport 1 Sub Main1 Dim i As Long Application.ScreenUpdating = False For i = 1 To 500 Worksheets("Sheet1").Activate Worksheets("Sheet1").Cells(i, 1).Select Selection.Copy Worksheets("Sheet2").Activate Worksheets("Sheet2").Cells(i, 3).Select Worksheets("Sheet2").Paste Destination:=Selection Next i Application.ScreenUpdating = True End Sub
これを下記のように直すと最後まで画面更新は止まります。Option VBASupport 1 Sub Main2 Dim i As Long Application.ScreenUpdating = False For i = 1 To 500 Worksheets("Sheet1").Cells(i, 1).Copy _ Destination:=Worksheets("Sheet2").Cells(i, 5) Next i Application.ScreenUpdating = True End Sub
ありがとうございます †
匿名 (2009-11-01 00:40:54 (日))
並び替えをしてあるシートを下から順に比較をしていって条件に合わなくなったら条件に合っていたものをすべて新規のシートに切り取って貼り付けるようなのを作成したのですが、Selectを多用しています。
なんとかSelectを減らすように検討してみます。
ありがとうございます。
確認ですが、Excelのように最初に指定したら解除するまで画面の更新を行わないようにする機能はないということでよろしいでしょうか?
無題 †
K.Tsunoda (2009-11-01 01:17:29 (日))
たぶん無いと思います。
とりあえず完了にします †
M.Kamataki (2009-11-01 22:33:51 (日))
K.Tsunodaさん、いろいろありがとうございます。
区切りの良いところで、とりあえず完了にしておきます。
完了にはなってますが… †
匿名 (2009-11-02 12:17:14 (月))
Selectを多用していた部分を別の記述に書き換えましたが、大して速度に違いがありませんでした。
お手数ですが、添削していただけないでしょうか?
シート名がcnv02でC列にある項目をシートに振り分けるものです。
Excelの場合は数秒で完了するのですが、この場合2分強掛かります。
なお、OOo.Basicの記述は全く理解していないので自動記録のものをそのまま流用しております。
無題 †
tani (2009-11-02 15:13:06 (月))
試してないので勘ですが、↓がなんかよくない気がします。Sheets("cnv02").Select '一番下から順にラインコードが変わるまで検索 r1 = Range("A65536").End(xlUp).Row c1 = Range("A65536").End(xlUp).Column While Cells(r1,c1).Offset(, 2) = Cells(r1,c1).Offset(-1, 2) r1 = r1 - 1 Wendこのへんの計算を、Do Untilループに入る前に事前にデータを配列に入れておいて、配列の計算にするようにしたら、ぐっと早くなるような気がします。
http://api.openoffice.org/docs/common/ref/com/sun/star/sheet/XCellRangeData.html
無題 †
K.Tsunoda (2009-11-02 17:15:20 (月))
テストはしていません。
敢えて出来るだけ原型を残す修正にしました。
> Dim r1 As Integer
> Dim c1 As Integer
行番号を扱うなら Long です。Integer(Max 32767)では 65536 はオーバーします。
列番号は256までですが、合わせて Long にしておいた方が良いでしょう。
> c1 = Range("A65536").end(xlUp).Column
A列で処理しているんですから、c1 = 1 で固定でしょう。
> While Cells(r1, c1).Offset(, 2) = Cells(r1, c1).Offset(-1, 2)
⇒ While Cells(r1, c1 + 2) = Cells(r1 - 1, c1 + 2)
⇒ While Cells(r1, 3).Value = Cells(r1 - 1, 3).Value
> While Cells(r1, 3).Value = Cells(r1 - 1, 3).Value
> r1 = r1 - 1
> Wend
> Range(Cells(r1, 1), Range("a65536").end(xlUp).end(xlToRight)).Cut
r2 を用意して、r1 の値を残せば、ここで再び end(xlUp) は不要でしょう。
r2 = r1 While Cells(r2, 3).Value = Cells(r2 - 1, 3).Value r2 = r2 - 1 Wend Range(Cells(r2, 1), Cells(r1, 1).end(xlToRight)).Cut
行によって使用範囲(列)が変わるんでしょうか?
切取り列範囲(右側)が固定ならend(xlToRight) も不要でしょう。
(コードを見るとK列までじゃないんですか?)Range(Cells(r2, 1), Cells(r1, 11)).Cut 'K列: 11(VBA)
Sheets("cnv02").Select r1 = Range("A65536").end(xlUp).Row r2 = r1 While Cells(r2, 3).Value = Cells(r2 - 1, 3).Value r2 = r2 - 1 Wend Range(Cells(r2, 1), Cells(r1, 11)).Cut add_sheet
OOo.Calc はセルを1つ1つ取り出して処理するのが、Excel と比べるのが
失礼なくらいに、べらぼうに【遅い】です。
tani さんが言うように配列に取り出してから処理しないと使い物になりません。
Dim vntWK As Variant Sheets("cnv02").Select r1 = Range("A65536").end(xlUp).Row 'vntWK = Range("A1:C" & r1).getDataArray 'Excel記法+ getDataArray はNG vntWK = ThisComponent.Sheets.getByName("cnv02").getCellRangeByName("A1:C" & r1).getDataArray r2 = r1 While vntWK(r2 - 1)(2) = vntWK(r2 - 2)(2) '配列はゼロから r2 = r2 - 1 Wend
セル範囲を配列に取り出す場合の配列の形態が Excel と Calc では異なります。
http://blog.livedoor.jp/addinbox/archives/51265222.html
ありがとうございます †
匿名 (2009-11-02 18:01:40 (月))
理解するのに時間が掛かると思いますが参考にさせていただきます。
やはり不要な部分が多いようですね…
分かる範囲で取り込ませていただきます。
ありがとうございます。