
お世話になります。
現在作っているコードがあるのですが、だいぶ処理時間がかかるのでもう少し早くしたいのですが何かいい案がないかお知恵を貸していただければと思っています。
色々処理をしているのですが、下記の提示箇所でほとんどの時間をくっていることが分かりました。
そのなかでもほとんどが行の高さをコピーして貼り付けていく所です。(Set myNewRng~Next m)
ある環境では、この処理で早くて1ループ6秒程度かかっています。10ループあれば1分かかってしまいます。
下記のコードはまず、貼り付け先に該当する場所が、原紙1でなければAllAddress(1)表をコピーして貼り付けています。
その後、行高さをコピーして貼り付けています。(列幅はこの前の段階でコピー貼り付け実行済み)
行高さ貼り付けは、myNewRngに高さ貼り付け先開始セルをセットし、mには、AllAddress(1)表の開始行と最後行をセットしておき、貼り付け元と貼り付け先を1行毎増やしながら行高さをコピーしていくやり方です。
表の行数や行高さなどは可変する可能性があります。
あとは、別シートから何個か必要なものを貼り付けています。
それを、i回繰り返し。
よろしくお願いいたします。
For i = LBound(mydicKey) To (UBound(mydicKey)) - 1
'1人毎コピーして貼り付け
If Not ws.Cells(StaRow(1) + (AllRow + AllRow * i), EndCol(2) + 2).Value = "原紙1" Then
ws.Range(AllAddress(1)).Copy ws.Cells((AllRow) * (i + 1) + 1, StaCol)
'行高さをコピー貼り付け('AllAddress(1)の開始セルからm行目までの行高さを順番にコピーし、
'myNewRngセルから下に向かって行高さを貼り付け変更していく)
Set myNewRng = ws.Cells((AllRow) * (i + 1) + 1, StaCol)
For m = StaRow(1) To EndRow(2)
myNewRng.Rows(m).RowHeight = ws.Range(AllAddress(1)).Rows(m).RowHeight
Next m
ws.Cells(StaRow(1) + (AllRow + AllRow * i), EndCol(2) + 2).Value = _
.Cells(12 + 1 + i, 2).Value
ws.Cells(1 + StaRow(1) + (AllRow + AllRow * i), EndCol(2) + 2).Value = _
.Cells(12 + 1 + i, 4).Value
ws.Cells(worker_nameRow(1) + (AllRow * (i + 1)), worker_nameCol(1)).Value = _
.Cells(12 + i + 1, 3).Value
ws.Cells(Range(ContactInfo(1)).Row + (AllRow * (i + 1)), Range(ContactInfo(1)).Column) = _
.Cells(12 + 1 + i, 6).Value
End If
Next i
A 回答 (7件)
- 最新から表示
- 回答順に表示
No.6
- 回答日時:
AllAddress(1)の範囲がいまいちわかりませんが、
Set myNewRng = ws.Cells((AllRow) * (i + 1) + 1, StaCol)
For m = StaRow(1) To EndRow(2)
myNewRng.Rows(m).RowHeight = ws.Range(AllAddress(1)).Rows(m).RowHeight
Next m
myNewRngは単セルで良いですか?
であれば、
For m = StaRow(1) To EndRow(2)
myNewRng.Rows(m).RowHeigh の意味はどうなりますか?
myNewRngもAllAddress(1)も共にm番目のRowを持っていると思いますが、、
AllAddress(1)はAllRow飛ばしのコピーを行っているので範囲があると思います。
Set myNewRng = ws.Cells((AllRow) * (i + 1) + 1, StaCol)は単セルを示しています。
もしFor mの為に範囲を持たせるのであれば、書き直す必要があると思いますが、推測するに
For m = StaRow(1) To EndRow(2)
myNewRng.Offset(m).Rows.RowHeight = ws.Range(AllAddress(1)).Rows(m).RowHeight
Next m
変数の代入方法など不明の為、該当しないかも知れませんが、、
No.5
- 回答日時:
横から失礼します。
処理速度が遅いのは、再計算停止をしても書式設定による表示処理が行われるのが原因だと思います。
(折り返しや縮小など)
なので、先にコピー先シートの列幅、行高さを設定りてから、対象にコピペすれば良いのではないでしょうか?
内容はよくわかりませんので未検証ですが、処理の順番を変えてみるのはいかがでしょう。
If Not ws.Cells(StaRow(1) + (AllRow + AllRow * i), EndCol(2) + 2).Value = "原紙1" Then
Set myNewRng = ws.Cells((AllRow) * (i + 1) + 1, StaCol)
For m = StaRow(1) To EndRow(2)
myNewRng.Rows(m).RowHeight = ws.Range(AllAddress(1)).Rows(m).RowHeight
Next m
ws.Range(AllAddress(1)).Copy ws.Cells((AllRow) * (i + 1) + 1, StaCol)
他のセルへの書き出しは、出来るなら配列などに纏め一度に書き込んだ方が処理は早いと思います。
的違いなら忘れてください。
ありがとうございます。
実測では速くはなりませんでしたが、ws.Range(AllAddress(1)).Copy myNewRng とシンプルに記載できることに気が付きました。
No.4
- 回答日時:
No.2です。
印刷の為の表であれば罫線など使用されていると思われますね。
値を省いても書式をペーストすれば罫線だけが貼りつく状態なので、初級レベルで言うなら現在やられている方法(1行ずつ合わせる)しかなさそうです。
表の固定化が困難であるなら避けられないのではないかと。
https://www.relief.jp/docs/excel-macro-copy-row- …
No.2
- 回答日時:
No.1です。
なんか思い浮かべられないのですが。
2つの表が左右で並んでいるとして、『とある列間では行の高さを広げ、その横では同じ行の高さを下げる』なんてExcelの仕様上無理なのでは?
なので2行を結合して広く『見せる』などの手段は用いた事ありますけど。
既に作成されている表では1行の高さを列の途中で列の高さを変更するなんて出来ているのでしょうか?(ちょっと前まで2002を弄ってたので機能の変化には追い付けてません)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 【ご教示ください】VBAの記述方法がわかりません。 2 2022/08/12 21:28
- Visual Basic(VBA) コード名シートA列と集計シートA列のコードが一致したら、コード名シートA5からk12の範囲をコピーし 1 2022/08/29 23:46
- Visual Basic(VBA) 【前回の続き続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/24 20:49
- Visual Basic(VBA) 【前回の続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/16 16:44
- Visual Basic(VBA) 他のシートからコピーする下記マクロで貼付け位置をWorksheets(1).Range("A3")の 8 2023/01/30 18:48
- Visual Basic(VBA) 【困っています2】VBA 追加処理の記述を教えてください。 2 2022/08/26 11:42
- Visual Basic(VBA) エラーコード1004 6 2022/06/09 14:12
- Excel(エクセル) 【困っています】VBA 追加処理の記述を教えてください。 1 2022/08/25 22:54
- Visual Basic(VBA) 【VBA】特定のワードが入っている行全体を塗りつぶしたい 4 2022/04/20 15:22
- Visual Basic(VBA) Excel VBA キーワードから列を取得して、さらに空欄行を非表示にする 3 2022/10/21 22:49
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
【マクロ】オートフィルターの...
-
エクセル:マクロ「Application...
-
エクセルのアポストロフィを一...
-
メールソフト「サンダーバード...
-
エクセルの2ページ目の作り方
-
Excel VBA コピーについて
-
シート毎にオートフィルタを実...
-
【エクセル】行の高さを規則的...
-
エクセルで隣接していない複数...
-
「選択範囲を解除してアクティ...
-
エクセルで勝手に「折り返して...
-
Excel 行の連続データを列に参...
-
Excelで、セルに数式ではなく、...
-
結合したセルを1つのセルにコピ...
-
エクセル 飛び飛びのセルの値...
-
セルが統合されている場合のコピー
-
エクセル 別シートへのコピー...
-
Excelで膨大なデータを処理する...
-
表の一部を計算式に
-
メモ帳の文章をExcelの1個のセ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセル:マクロ「Application...
-
エクセルのアポストロフィを一...
-
エクセルで勝手に「折り返して...
-
エクセルで隣接していない複数...
-
メールソフト「サンダーバード...
-
【マクロ】オートフィルターの...
-
エクセルの2ページ目の作り方
-
Excel 行の連続データを列に参...
-
エクセルで、選択範囲の数値全...
-
エクセル 別シートへのコピー...
-
「選択範囲を解除してアクティ...
-
Excelに、ダブルクォーテーショ...
-
エクセルで値だけコピーして背...
-
エクセルで「コピーしたセルの...
-
EXCEL数値が存在する列の項目名...
-
エクセル コピーしたデータを1...
-
行数の違う表に複数行をコピーする
-
EXCELで「行と列を入れ替える」...
-
エクセルでの行数・列数を指定...
-
エクセル・数値が変化したらカ...
おすすめ情報
ありがとうございます。
表なのですが、この度作成したものは自分で好きな表を作成して扱えるように作りました。よって、表は様々であり固定ではありません。(実際は固定して使うと思いますが途中で変更しても問題ないようにしています)
コピペ時の書式貼り付けですが、列幅は出来ると思いますが行高さをコピーすることは出来るのでしょうか?行全体をコピーした場合であればそのまま行高さをコピーできると思いますが、現在行っているものは、印刷時左右2つの表を印刷する作りにも対応させ、さらに条件で左の表や右の表だけ印刷などにも対応させる為に行全体のコピーではなく表毎のコピーにしています。
表全体を選択してコピー貼り付けする時に行高さも貼り付けることが可能であればありがたいですが、出来ますか?その操作が可能であれば他への影響はありません。
説明が悪かったのですが、並んだ表は当然同じ行高さです。
行コピーで貼り付けていない理由を説明したかったのですが、例えば条件によって同じ行に並んでいる右の表だけ必要で左表はコピーしたくない場合もある為、行コピーは行っておらず表毎のコピーを実施しています、ということが言いたかったのですが、意味分かりますか?
表の行毎の高さは様々ですし、固定もされません。
ちなみに、さらに言うと左右に並んだ表というパターンの他、上下2つの表を別のものとして並べるパターンもあります。基本的には、同じパターンで作成すると想定されますが、行高さは上下で違うものでも大丈夫にしたくて1行処理を行った結果、かなり時間を食う事が発覚してしまいました。上下2つや左右2つの表は、当然分岐処理で分けるべきところは分けて処理しています。
セル範囲のコピーなので当然行高さはコピーされないので、何とかならないかな、と思っています。
その辺りは、実施しております。イベント停止や再計算停止とかも。
myNewRngは単セルではありますが、起点セルとして使っています。
例えばA1:O31範囲の表があるとして、
AllRow = Range(lastAddress(1)).Rowで31ですね。A1:O31表を計算して下方向へずらしながら貼り付けていくイメージです。mは表の開始行と終わり行です。
右辺のws.Range(AllAddress(1)).Rows(m).RowHeightが元表の開始行から終わり行までを順に巡ります。左辺では、起点セルmyNewRngから行位置を取得しています。
と思ってやっていましたが、.Offset(m).Rowsでも動作しました。ぱっと見はこっちの方が分かりやすいですね。時間は特に変化なしです。
Rowsというのはこういう使い方ありでは?
For i = 1 To 10
Range("A1").Rows(i) = 30
Next i
A1:A10に30入力
自分でもう少し工夫しました。
できるところは、行丸ごとコピーに変更し1行毎の高さコピーを減らしました。
また、1行毎に行高さをコピーしないといけない所では、動的配列rowNumに入れてやると13秒→9秒位に短縮できました。文字数制限で端折ります。まだ、遅いですが少しましに。
For m = ××
rowNum(m - 1) = ws.Range(AllAddress(1)).Rows(m).RowHeight
Next m
Set myNewRng = ××
For m = LBound(rowNum) To UBound(rowNum)
myNewRng.Rows(m + 1).RowHeight = rowNum(m)
Next m
ws.Range(AllAddress(1)).Copy myNewRng
時間がかかる処理なのかなと思いこんでいましたが、新しいので、適当に同じくらいの行を処理したのですが、同じようなやり方でもあっという間に終わりました。
Selectしながら行の貼り付け元と貼り付け先の動きを確認しましたが、予期せぬ所をつかんでいるようなことはなかったです。
あきらめて、行丸ごとコピー方式に変更しました。
速くはないけど厳しそうな条件で動かして、飛び飛びの複雑な改ページ設定などもして印刷ダイアログ開くまでもっていくのに23秒だったのでまあ使えるレベルになったかなと思います。(最初は2分近くかかっていたと思う)
デバック中に何度もクラッシュ起こしているので、完全に他の部分も終わったら、新規ブックに移設して使いたいと思います。
お付き合いいただきありがとうございました。