Excel (VBA) |
![]() ![]() |
(指定なし : 指定なし)
計算の高速処理
投稿日時: 23/09/13 07:37:15
投稿者: yama1006
|
---|---|
毎度恐縮です。
|
![]() |
投稿日時: 23/09/13 09:34:35
投稿者: WinArrow
|
---|---|
VLOOKUPで参照する範囲は、いつも同じですよね?
|
![]() |
投稿日時: 23/09/13 09:48:28
投稿者: WinArrow
|
---|---|
追加質問
引用: 1行目のコードの目的は? 2行目のコード Vlookup関数の検索値は、「値」ですから、ary1(s,1)で、代用できます。 わざわざ、rngオブジェクトを使う必要もないでしょう。 |
![]() |
投稿日時: 23/09/13 16:11:15
投稿者: 半平太
|
---|---|
一見した限りでは、さほど遅そうな気もしないです。(最近のエクセルは早いですからねぇ・・)
|
![]() |
投稿日時: 23/09/14 05:36:55
投稿者: yama1006
|
---|---|
WinArrow さんの引用: 大変勉強になります。 ary1 = ws2.Range("b2").CurrentRegion ’最終抽出者シートの最終行を取得 このためだけにコードを入れました。 |
![]() |
投稿日時: 23/09/14 05:40:40
投稿者: yama1006
|
---|---|
半平太 さんの引用: おっしゃる通りでした。修正します。。。。。 多いところだと1000人以上いたりします。シートの枚数もだいたい4〜5枚ある時を想定します。 所要時間ですと現在の方法だと38人だけで20秒くらいかかってます。 |
![]() |
投稿日時: 23/09/14 11:05:47
投稿者: higejee
|
---|---|
なにはともあれ最初に
|
![]() |
投稿日時: 23/09/14 22:03:23
投稿者: 半平太
|
---|---|
>シートの枚数もだいたい4〜5枚ある時を想定します。
Sub 月額変更() Dim ws月額予定一覧表 As Worksheet Dim ws最終抽出 As Worksheet Dim ws標準報酬 As Worksheet Dim ws As Worksheet Dim c As Long Dim n As Long Dim s As Long Dim rng As Range Dim rng2 As Range Dim rng3 As Range Dim rng4 As Range Dim lastrow As Long Dim lastcolumn As Long Dim ary1 As Variant Set ws月額予定一覧表 = Sheets("月額予定一覧表") Set ws最終抽出 = Sheets("最終抽出") Set ws標準報酬 = Sheets("標準報酬") 'C列から値を 配列Ary1 に格納する ary1 = Intersect(ws最終抽出.Range("b2").CurrentRegion, ws最終抽出.Columns("C:O")).Value For s = 2 To UBound(ary1) '最終抽出者の人数 Set rng = ws最終抽出.Cells(s, 2) 'vlookの参照値 Dim posInWs月額予定一覧表ColB posInWs月額予定一覧表ColB = WorksheetFunction.Match(rng, ws月額予定一覧表.Columns("B"), 0) ary1(s, 1) = ws月額予定一覧表.Cells(posInWs月額予定一覧表ColB, 18) '前3月 ary1(s, 3) = ws月額予定一覧表.Cells(posInWs月額予定一覧表ColB, 20) '前2月 ary1(s, 5) = ws月額予定一覧表.Cells(posInWs月額予定一覧表ColB, 22) '前1月 ary1(s, 2) = ws月額予定一覧表.Cells(posInWs月額予定一覧表ColB, 19) '標準報酬月額前3月 ary1(s, 4) = ws月額予定一覧表.Cells(posInWs月額予定一覧表ColB, 21) '標準報酬月額前2月 ary1(s, 6) = ws月額予定一覧表.Cells(posInWs月額予定一覧表ColB, 23) '標準報酬月額前1月 For n = 2 To ThisWorkbook.Sheets.Count Set ws = Worksheets(n) If ws.Name <> "最終抽出" Then 'シート最終抽出以外 If ws.Name <> "標準報酬" Then 'シート標準報酬以外 If ws.Name <> "月額予定一覧表" Then 'シート月額予定一覧表以外 Dim posInWsColB posInWsColB = WorksheetFunction.Match(rng, ws.Columns("B"), 0) c = ws.Cells(posInWsColB, "D") * -1 '前3月の合計金額 ary1(s, 2) = ary1(s, 2) + c c = ws.Cells(posInWsColB, "E") * -1 '前2月の合計金額 ary1(s, 4) = ary1(s, 4) + c c = ws.Cells(posInWsColB, "F") * -1 '前1月の合計金額 ary1(s, 6) = ary1(s, 6) + c End If End If End If Next Set rng2 = ws最終抽出.Cells(s, 9) Set rng3 = ws最終抽出.Cells(s, 12) ary1(s, 7) = WorksheetFunction.RoundUp((ary1(s, 2) + ary1(s, 4) + ary1(s, 6)) / 3, 0) '3月の平均金額 ary1(s, 8) = WorksheetFunction.VLookup(rng, ws月額予定一覧表.Range("b:y"), 9, 0) '従前等級健保 ary1(s, 9) = WorksheetFunction.VLookup(rng, ws月額予定一覧表.Range("b:y"), 11, 0) '従前等級厚年 ary1(s, 10) = WorksheetFunction.VLookup(rng2, ws標準報酬.Range("a:e"), 2, 1) '現等級健保 ary1(s, 11) = WorksheetFunction.VLookup(rng2, ws標準報酬.Range("a:e"), 4, 1) '現等級厚年 ary1(s, 12) = WorksheetFunction.VLookup(rng3, ws標準報酬.Range("b:c"), 2, 1) '予定等級健保 ary1(s, 13) = WorksheetFunction.VLookup(rng3, ws標準報酬.Range("d:e"), 2, 1) '予定等級厚年 Next '書き出し ws最終抽出.Range("C1").Resize(UBound(ary1), UBound(ary1, 2)) = ary1 End Sub |
![]() |
投稿日時: 23/09/15 06:03:26
投稿者: yama1006
|
---|---|
higejee さんの引用: そうですね。こちらも実装します。ありがとうございます。 |
![]() |
投稿日時: 23/09/15 06:06:59
投稿者: yama1006
|
---|---|
|
![]() |
投稿日時: 23/09/15 09:06:06
投稿者: higejee
|
---|---|
勝手に代返しますが、二次元配列 ary1 の全要素を、同じサイズのセル領域に(一括して)書き出す、ということです。個々のセルにひとつずつ書き出すより確実に早いです。 |
![]() |
投稿日時: 23/09/15 12:06:10
投稿者: simple
|
---|---|
処理の前に、
Dim t t = Timerを挿入し、 処理後に Debug.Print Timer - tとすることで、実行時間(秒)をイミディエイトウインドウに出せます。 現状、及び皆さんの回答について、それぞれ所要時間を示されるとよいでしょう。 |
![]() |
投稿日時: 23/09/20 04:58:23
投稿者: yama1006
|
---|---|
|
![]() |
投稿日時: 23/09/20 04:59:42
投稿者: yama1006
|
---|---|
higejee さんの引用: ご教示ありがとうございます。 このように配列に格納して後で一気に書き出すという手法、今回のコードで何となくわかってきました。また挑戦してみます。 |
![]() |
投稿日時: 23/09/20 05:00:12
投稿者: yama1006
|
---|---|
simple さんの引用: ご教示ありがとうございます。今度からそうします。 |