EXCELマクロの処理時間を短縮したい

このQ&Aのポイント
  • Windows XP ProとEXCEL 2002を使用している状況で、EXCELマクロの処理時間が長くなって困っています。具体的な作業内容はOLEDBを使って他のDBからデータを展開し、そのデータを一覧に整理するというものです。処理に時間がかかる要因は、シートAのデータ件数が約4万件であり、シートMのデータ件数も約3万件あるためです。これらの処理をより効率的に実行する方法を教えてください。
  • マクロのソースコードでは、収集したデータをシートAとシートMに展開しています。シートAのデータは番号、コード、数量、単価、追加数量、追加単価の情報を持っています。シートMのデータはコードと名称の情報を持っています。これらのデータを基本番号別に整理し、金額を計算してシート一覧に表示するという処理です。
  • 具体的なマクロソースコードは、シートAのデータを一時的に読み込み、基本番号と枝番を考慮して一覧にコピーしている部分と、シートMのデータを基本番号に紐づけて名称を一覧に入力している部分です。マクロソースコードによる処理時間の短縮が望まれます。
回答を見る
  • ベストアンサー

EXCELマクロの処理時間を短縮したい

EXCELマクロの時間短縮で悩んでいます。どうかお知恵をお貸し下さい。(長文です) Windows XP Pro EXCEL 2002 を使用しています。 以下の作業の2.のところで2分以上 3.のところで2分以上の時間が掛かっています マクロソースによるこれ以上の短縮は望めないでしょうか?  <作業内容> 1. OLEDBを使って他のDBから  トランザクション「A」のデータを シート「A」に  マスタ「M」のデータを シート「M」に展開しています 2. シート「A」のデータは 約40,000件 (変動します)  番号    基本番号+枝番(1桁) 最初は基本番号+0で変更があると枝番をカウントアップして追加  最新番号  変更が合った場合 変更の回数(枝番=0のレコードだけ更新)  コード   名称コード   数量    単価    小数点以下 2桁まで  追加数量    追加単価   番号  |最新番号|コード| 数量 | 単価 | 追加数量|追加単価|   1000010 | 0 |123456| 1,000|100.30| 10|1,000.00|   1000020 | 2 |111111| 1,000|200.50| 1|5,000.00|   1000021 | 0 |111111| 900|200.50| 2|5,000.00|   1000022 | 0 |111111| 1,000|200.00| 1|5,000.00|   1000030 | 0 |123000| 2,500| 90.75| 0| 0.00|   9500010 | 0 |999999| 0| 0.00| 0| 0.00|  これを シート「一覧」に基本番号別に枝番が最新の行をコピーして金額を出します  約 35,000件になります  基本番号 |コード| 名称 | 数量 | 単価 | 追加数量|追加単価| 金額   100001 |123456| | 1,000|100.30| 10|1,000.00|110,300   100002 |111111| | 1,000|200.00| 1|5,000.00|205,000   100003 |123000| | 2,500| 90.75| 0| 0.00|226,875 3. シート「M」のデータは 約30,000件 (変動します)   コード |  名称  |    111111| AAAAAAAAAA | 123000| ABCDEFGHIJ | 123456| BBBBBBBBBB |  シート「一覧」の名称に名称を入れます  基本番号 |コード|  名称 | 数量 | 単価 | 追加数量|追加単価| 金額   100001 |123456|BBBBBBBBBB| 1,000|100.30| 10|1,000.00|110,300   100002 |111111|AAAAAAAAAA| 1,000|200.00| 1|5,000.00|205,000   100003 |123000|ABCDEFGHIJ| 2,500| 90.75| 0| 0.00|226,875 <マクロ ソース> Sub 一覧作成() Dim i As Long, j As Long, k As Long, read_no As Long Dim jlist As Worksheet, jdata As Worksheet Dim v As Variant, w As Variant Dim dic As Object Application.ScreenUpdating = False '画面停止 'DB取り込み ※省略 Set jlist = Worksheets("一覧") '処理2 Set jdata = Worksheets("A") jlist.Cells.ClearContents jlist.Range("A1").Value = "基本番号" jlist.Range("B1").Value = "コード" jlist.Range("C1").Value = "名称" jlist.Range("D1").Value = "数量" jlist.Range("E1").Value = "単価" jlist.Range("F1").Value = "追加数量" jlist.Range("G1").Value = "追加単価" jlist.Range("H1").Value = "金額" i = 2 '今読んでる行 k = 2 '書いている行 j = 0 '枝番が合った場合 飛ばす行 read_no = 0 Do While jdata.Cells(i, 1).Value < 9500000 read_no = jdata.Cells(i, 1).Value / 10 j = 0 If jdata.Cells(i, 2).Value <> 0 Then '枝番有 j = judata.Cells(i, 2) End If i = i + j jlist.Cells(k, 1).Value = Format(read_no, "000000") jlist.Cells(k, 2).Value = jdata.Cells(i, 3).Value jlist.Cells(k, 4).Value = jdata.Cells(i, 4).Value jlist.Cells(k, 5).Value = jdata.Cells(i, 5).Value jlist.Cells(k, 6).Value = jdata.Cells(i, 6).Value jlist.Cells(k, 7).Value = jdata.Cells(i, 7).Value jlist.Cells(k, 8).Value = _ Application.RoundDown((jdata.Cells(i, 4).Value * jdata.Cells(i, 5).Value + _ jdata.Cells(i, 6).Value * jdata.Cells(i, 7).Value), 0) k = k + 1 i = i + 1 Loop Set jname = Worksheets("M") '処理3 With jname With .Range("B2", .Cells(.Rows.Count, 1).End(xlUp)) v = .Columns(1).Value w = .Columns(2).Value End With End With Set dic = CreateObject("scripting.dictionary") For i = 1 To UBound(v) dic(v(i, 1)) = i Next With jlist With .Range("B2", .Cells(Rows.Count, 4).End(xlUp)) 'B2~Dの最終行まで v = .Value For i = 1 To UBound(v) If dic.exists(v(i, 1)) Then v(i, 2) = w(dic(v(i, 1)), 1) Else v(i, 2) = "無" End If Next With .Offset(0, 0) .ClearContents .Value = v End With End With End With Set dic = Nothing Set jlist = Nothing Set jname = Nothing Application.ScreenUpdating = True End Sub

質問者が選んだベストアンサー

  • ベストアンサー
  • end-u
  • ベストアンサー率79% (496/625)
回答No.2

>Do While jdata.Cells(i, 1).Value < 9500000 >  read_no = jdata.Cells(i, 1).Value / 10 >  j = 0 >  If jdata.Cells(i, 2).Value <> 0 Then  '枝番有 >    j = judata.Cells(i, 2) >  End If >  i = i + j >  jlist.Cells(k, 1).Value = Format(read_no, "000000") >  jlist.Cells(k, 2).Value = jdata.Cells(i, 3).Value >  jlist.Cells(k, 4).Value = jdata.Cells(i, 4).Value >  jlist.Cells(k, 5).Value = jdata.Cells(i, 5).Value >  jlist.Cells(k, 6).Value = jdata.Cells(i, 6).Value >  jlist.Cells(k, 7).Value = jdata.Cells(i, 7).Value >  jlist.Cells(k, 8).Value = _ >  Application.RoundDown((jdata.Cells(i, 4).Value * jdata.Cells(i, 5).Value + _ >              jdata.Cells(i, 6).Value * jdata.Cells(i, 7).Value), 0) >  k = k + 1 >  i = i + 1 >Loop この箇所、1セルずつ書き込んでいますから遅いです。 Sheets("A")のデータを配列に取り込んで、同行8列の配列を作って処理し、 Sheets("一覧")に一括で書き込むようにしたほうが速くなります。 具体的には >'i = 2    '今読んでる行 >'k = 2    '書いている行 >'j = 0    '枝番が合った場合 飛ばす行 >'read_no = 0 以上は不要。 : With jdata   'Sheets("A")のA列最下行からG2セルまでのデータ部を配列に   v = .Range("G2", .Cells(.Rows.Count, 1).End(xlUp)).Value End With 'vと同サイズ(列は8)の空配列準備 ReDim w(1 To UBound(v), 1 To 8) '書き込み位置 k = 0 '配列1次元の要素の数だけLoop For i = 1 To UBound(v)   '一応、Loop終了条件踏襲   If v(i, 1) >= 9500000 Then     Exit For   End If   read_no = v(i, 1) / 10   If v(i, 2) <> 0 Then '枝番有     i = i + v(i, 2)   End If   k = k + 1   w(k, 1) = Format(read_no, "000000")   w(k, 2) = v(i, 3)   w(k, 4) = v(i, 4)   w(k, 5) = v(i, 5)   w(k, 6) = v(i, 6)   w(k, 7) = v(i, 7)   w(k, 8) = Application.RoundDown((v(i, 4) * v(i, 5) + _                    v(i, 6) * v(i, 7)), 0) Next 'kがwの書き込み数なのでSheets("一覧")の範囲をResizeして書き込み jlist.Range("A2:H2").Resize(k).Value = w : こんな感じです。 もしかしたらRoundDown計算は一度Sheets("A")のH列でやってから 配列に一緒に取り込むようにしたほうが速いかもしれません。 また、dictionaryを使った名称セットも 上記Loopの中でやってしまっても良いかもしれませんね。

ishi_rin
質問者

お礼

ありがとうございます。 おかげ様で2.の処理があっという間に終わるようになりました。 No.3で頂いた回答と合せて 5分近く掛かっていた処理が30秒掛からず終了するようになりました。 回答して頂いた皆様に感謝いたします。

その他の回答 (3)

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.4

3の所だけ試験データを作成してやってみました。xl2000,WindowsXP SP3,PentiumM 1.3Gの古いマシンです。 ご提示のコードより単純な方法で、同等の事をしているつもりですが、数秒で終了しました。ご参考まで。 Sub test3() Dim myDic As Object Dim i As Long Dim targetRange As Range Dim buf As Variant Application.ScreenUpdating = False Set myDic = CreateObject("scripting.dictionary") Set targetRange = Sheets("M").Range("A2:B30001") buf = targetRange For i = LBound(buf, 1) To UBound(buf, 1) myDic.Add buf(i, 1), buf(i, 2) Next i Set targetRange = Sheets("一覧").Range("A2:H35001") buf = targetRange For i = LBound(buf, 1) To UBound(buf, 1) If myDic.exists(buf(i, 2)) Then buf(i, 3) = myDic(buf(i, 2)) Else buf(i, 3) = "無" End If Next i targetRange = buf Application.ScreenUpdating = True End Sub

ishi_rin
質問者

お礼

ありがとうございます。 皆様にお教え頂いた結果 時間短縮に成功いたしました。

  • end-u
  • ベストアンサー率79% (496/625)
回答No.3

>..3.のところで2分以上.. 処理3はdictionaryと配列を使ってるのにそんなにかかりますか。 ひょっとしたら別の原因で遅くなってるのかも。 ScreenUpdatingプロパティだけではなく、 (処理前) Dim x As Long With Application   x = .Calculation   .Calculation = xlCalculationManual   .EnableEvents = False   .ScreenUpdating = False End With : (処理後) With Application   .Calculation = x   .EnableEvents = True   .ScreenUpdating = True End With のように、イベントと再計算の制御もやったほうが良いかもしれません。 それに処理3を弄るとしたら : Set jname = Worksheets("M") With jname   With .Range("B2", .Cells(.Rows.Count, 1).End(xlUp))     v = .Columns(1).Value     w = .Columns(2).Value   End With End With Set dic = CreateObject("scripting.dictionary") For i = 1 To UBound(v)   dic(CStr(v(i, 1))) = i Next With jlist   With .Range("B2", .Cells(.Rows.Count, 2).End(xlUp))     v = .Value     ReDim z(1 To UBound(v), 0) As String     For i = 1 To UBound(v)       j = dic(CStr(v(i, 1)))       If j = 0 Then         z(i, 0) = "無"       Else         z(i, 0) = w(j, 1)       End If     Next     .Offset(, 1).Value = z   End With End With こんな感じでしょうか。

ishi_rin
質問者

お礼

ありがとうございます。 おかげ様で 3.の処理が10秒程度で終わるようになりました。

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.1

望む回答ではないだろうが、 (1)2つのエクセルシートに、OLEDBを使って他のDBから、 トランザクション「A」のデータを シート「A」に マスタ「M」のデータを シート「M」に展開して、処理はせずに時間を計る(プログラムを加える)。 シートデータを一旦保存。 (2)次に(データベースのデータは使わず・読まず)両シートだけを読んで処理するプログラムに(改変は一部で済むと思うが)変える。 (処理時間を計るプログラムを加える) (2)では現状より相当短縮されるなら、OLEDBを使って他のDBから、エクセルシートへが要因ではないか。 原因追求には、どんなことでも、こういう切り分けが必要だろう。 2重ループもないようだし、コードだけから割り出すのは難しいのでは。 木になるのはFSOのDictionaryという素人受けの仕組みを使っているようなこと。 すばらしい仕組みだが時間はかかるのではないかな。 ソート法でソートし、マッチングアルゴリズムを使えば速くなると思うが、やっている内容がよくわからないので何ともいえない。 === 別のことだが、全体的に何がしたいのか、質問文章で表現できないのか。 質問にはSet jlist = Worksheets("一覧")'処理2からjlist.Range("H1").Value = "金額"までなど1回限りのことで書く必要は無いだろう。 前半は1歩1歩書いてあるようでいて、その後は単純な順処理なのか、マッチング的なことなのか何がしたいのか、判りにくい。 データは再現できないし、テストも出来ない。 もっと読者・回答者のことを慮って、質問の表現・内容を考えててほしい。コードを丸写しでなく、処理内容の解説がほしい。この質問を見たらパスする人が多いのでは。

ishi_rin
質問者

お礼

ありがとうございます。 文章が判りにくく申し訳ありません。ご親切な皆様に助けていただいています。

関連するQ&A

  • VBA マクロ処理時間の短縮について

    下記のコードを作りましたが、マクロを実行すると砂時計マークが表示されて、処理が終了するまでに30秒くらいかかります。 コードを変更して、マクロ処理時間を短縮する事はできないでしょうか? Sub A列のコピー() Dim rw2 As Long Dim rw1 As Long Dim newdate As Date With Worksheets("sheet1") rw2 = .cells(.Rows.Count, "c").End(xlUp).Row newdate = .Range("c" & rw2).value For rw1 = rw2 - 1 To 1 Step -1 If .Range("c" & rw1).value <> newdate Then Exit For Next rw1 .Range(.cells(rw1 + 1, 1), .cells(rw2, 1)).Copy Worksheets("sheet2").Range("v6").PasteSpecial xlValue If rw1 + 26 <= rw2 Then .Range(.cells(rw1 + 26, 1), .cells(rw2, 1)).Copy Worksheets("sheet2").Range("v40").PasteSpecial xlValue Application.CutCopyMode = False End If Application.CutCopyMode = False End With End Sub 各セルは、6000行くらいまで表示されています。  よろしくお願いします。

  • マクロdictionaryオブジェクト書き換え

    ここで教えていただいたマクロを   シート1のF列を検索値として   シート2のA列を検索しヒットしたら   シート2の該当行のD列をシート1のAE列に転記。   データの2列目から行う。ヒットしない場合は 無 と転記。 と変更したくて記述を書き換えたらシート1が壊れてしまいました。 正しい記述を教えてください。 ↓教えていただいた書き換え前の正常動作する記述↓ Sub 検索() 'dictionaryオブジェクトを使用 'シート1のA列を検索値として 'シート2のA列を検索しヒットしたら 'シート2の該当行のE列をシート1のC列に転記 'データの2行目から行う。ヒットしない場合は無しと転記 Dim dic As Object Dim i As Long Dim v, w Dim t As Single t = Timer With Sheets("Sheet2") '返す値を指定E列 With .Range("E2", .Cells(.Rows.Count, 1).End(xlUp)) '検索する列指定 (1)=A列 v = .Columns(1).Value '返す値のある列指定 (5)=E列 w = .Columns(5).Value End With End With Set dic = CreateObject("scripting.dictionary") For i = 1 To UBound(v) dic(v(i, 1)) = i Next With Sheets("Sheet1") '検索値のある列指定 A列 With .Range("A2", .Cells(.Rows.Count, 1).End(xlUp)) v = .Value For i = 1 To UBound(v) If dic.exists(v(i, 1)) Then v(i, 1) = w(dic(v(i, 1)), 1) Else v(i, 1) = "無" End If Next '転記する列を指定 Offset(, 2)=検索値のA列より右2つ→C列 With .Offset(, 2) .ClearContents .Value = v End With End With End With Set dic = Nothing Debug.Print Timer - t End Sub ---- ↓書き換えておかしな動きになった物 ●の部分を変更しました↓ Sub 検索02() 'dictionaryオブジェクトを使用 'シート1のF列を検索値として 'シート2のA列を検索しヒットしたら 'シート2の該当行のD列をシート1のAE列に転記 'データの2行目から行う。ヒットしない場合は無しと転記 Dim dic As Object Dim i As Long Dim v, w Dim t As Single t = Timer With Sheets("Sheet2") '返す値を指定D列● With .Range("D2", .Cells(.Rows.Count, 1).End(xlUp)) '検索する列指定 (1)=A列 v = .Columns(1).Value '返す値のある列指定 (4)=D列● w = .Columns(4).Value End With End With Set dic = CreateObject("scripting.dictionary") For i = 1 To UBound(v) dic(v(i, 1)) = i Next With Sheets("Sheet1") '検索値のある列指定 F列● With .Range("F2", .Cells(.Rows.Count, 1).End(xlUp)) v = .Value For i = 1 To UBound(v) If dic.exists(v(i, 1)) Then v(i, 1) = w(dic(v(i, 1)), 1) Else v(i, 1) = "無" End If Next '転記する列を指定  'Offset(, 25)=検索値のA列より右25個→AE列● With .Offset(, 25) .ClearContents .Value = v End With End With End With Set dic = Nothing Debug.Print Timer - t End Sub

  • エクセル2010でマクロが動きません

    こんにちは。 マクロ超初心者です。 頑張ってエクセル2016でマクロ作成しましたが、エクセル2010で途中から動かず…。 何が悪いんでしょうか… ここから動きません…と書いたところから動きません(涙) Private Sub シート編集_Click() Application.ScreenUpdating = False Dim i Dim Sh1 As Worksheet Dim Sh2 As Worksheet Dim Sh4 As Worksheet Set Sh1 = Worksheets("あ") Set Sh2 = Worksheets("い") Set Sh4 = Worksheets("う") Dim dayCutoff As Date dayCutoff = Application.InputBox("年月日を入力してください", "お支払期限 年月日を入力", Format(Date, "yyyy/mm/dd")) Sh4.Range("D12").Value = DateSerial(Year(dayCutoff), Month(dayCutoff) + 2, 0) 'お支払期限 dayCutoff = Application.InputBox("年月日を入力してください", "請求書発行 日を入力", Format(Date, "yyyy/mm/dd")) Sh4.Range("AC3").Value = Format(Date, "yyyy/mm/dd") '発行日 Sh1.Cells.Clear With Sh1 'edit .Range("A2") = "番号" .Range("B2") = "会社名" .Range("C2") = "判定" .Range("D2") = "契約番号" .Range("E2") = "拠点" .Range("F2") = "税率" .Range("G2") = "月額(税抜)" .Range("H2") = "消費税" .Range("I2") = "月額(税込)" .Range("J2") = "今回" .Range("K2") = "全回" .Range("L2") = "店番" ここから動きません………… For i = 3 To Sh2.Cells(.Rows.Count, 1).End(xlUp).Row .Cells(i, 1) = Sh2.Cells(i, 2) .Cells(i, 2) = Sh2.Cells(i, 4) .Cells(i, 4) = Sh2.Cells(i, 3) .Cells(i, 5) = Sh2.Cells(i, 4) & "(" & Sh2.Cells(i, 6) & ")" .Cells(i, 6) = Sh2.Cells(i, 9) & "%課税" .Cells(i, 7) = Sh2.Cells(i, 8) .Cells(i, 8) = Sh2.Cells(i, 10) .Cells(i, 9) = Sh2.Cells(i, 11) .Cells(i, 10) = Sh2.Cells(i, 12) .Cells(i, 11) = Sh2.Cells(i, 7) .Cells(i, 12) = Sh2.Cells(i, 2) If Sh1.Cells(i, 10) > Sh1.Cells(i, 11) Then .Cells(i, 3) = "×" Else .Cells(i, 3) = "〇" End If If Sh1.Cells(i, 3) = "×" Then .Cells(i, 2) = "" End If Next i End With '空白行を削除 Dim j As Integer, myFlag As Boolean Dim c As Range With Worksheets("edit").Range("A2").CurrentRegion For j = .Rows.Count To 2 Step -1 myFlag = False For Each c In .Cells(j, 2) If c.Value <> "" Then myFlag = True Exit For End If Next If myFlag = False Then .Rows(j).Delete End If Next End With MsgBox "データの転記が終わりました" End Sub

  • エクセル マクロ 抽出

    教えてください。 ○と記入されたセルを参照して、一つ上のセル・A列にある同じ行のセル・ 9行目にある同じ列のセルを抽出しようとしています。 下記の通り入力すると 行数=値.Rowでエラーが出たしまいました。 試行錯誤頑張りましたが解決できそうにありませんのでお力を貸して頂けないでしょうか。 Sub 抽出() Dim i, 行数, 列数 As Long Dim 値 As Range i = 0 行数 = 値.Row 列数 = 値.Column For Each 値 In Sheets("sheet1").Range("C12:R171") If 値.Value = "○" Then i = i + 1 With Sheets("sheet2") .Cells(i, 3).Value = Sheets("sheet1").Cells(行数, 1).Value .Cells(i, 4).Value = Sheets("sheet1").Cells(9, 列数).Value .Cells(i, 5).Value = 値.Offset(-1, 0).Value End With End If Next End Sub

  • 現マクロに列の塗りつぶし追加したい

    マクロについては素人の私です。 図を参照いただきたいですが、J2にリストで「入金済み」と入力したとき下記のマクロでは F2 G2 I2 J2がグレーに塗りつぶしています。 但しE2には次のような式が入っています。 =IF(OR(B2="",C2=""),"",TEXT(B2,"yymmdd")&C2) このような式が入っていてもE2の塗りつぶしは可能でしょうか。可能ならば追加したいです。不可能ならE2は除きます。 もし可能ならばこれを B2 C2 D2 E2 もグレーでセルを塗りつぶすのを追加したいが下記のマクロをどうすればよろしいでしょうか。 Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) Dim i As Long Dim r As Byte i = Sheets("入金記入").Range("B65536").End(xlUp).Row + 1 r = Target.Row If Target.Value = "入金済" Then With Sheets("入金記入") .Cells(i, 2).Value = Date .Cells(i, 3).Value = Cells(r, 3).Value .Cells(i, 4).Value = Cells(r, 4).Value End With End If End Sub ご指導の程、よろしく御願いします。

  • エクセル 2010 マクロ 検索

    http://okwave.jp/qa/q8562170.html 上記質問に追加です。 ※1 'D,E,F,G,H,I,K を検索してD,E,F,G,H,I に検索対象があった時 E,F,G,H,Iのいずれかだったら左横列の上に向かって (EならD 、FならE ・・・という具合に) 何か入力されているセルのM列の191000####をmsgboxで表示させたいです。 (画 F11セル(A-1)が検索ヒットした場合E9セル(R-01)を辿り、 その行のM列のセル(191000####)をmsgboxで表示 ※2 但し、検索結果がD列のデータだった時、その行のM列が191000####だった場合 M列の191000####をmsgboxで表示させたいです。 (画 D25セル(Y-1)対象の時) ※3 また、検索結果がD列のデータだった時、その行のM列が191000####以外だった場合 (空白だったり191000####以外の場合) M列の一番上の191000####をmsgboxで 191000####&「これは例外です」と表示させたいです。 (画 D24セル (X-1)対象の時) 現在のコードは下記のとおりです。 Sheet1に Private Sub Worksheet_SelectionChange(ByVal Target As Range) If Target.Address <> "$A$3" Then Exit Sub Call 検索 Range("A1:A2").Clear Range("A1").Activate End Sub 標準モジュールに Sub 検索()  Dim Ws1 As Worksheet, Ws2 As Worksheet  Dim strKey As Variant  Dim s As String  Dim c As Range, bln As Boolean  Dim rng1 As Range  Dim cnt As Long    Set Ws1 = Sheet1  Set Ws2 = Sheet2    Ws1.Select    With Ws2   strKey = Application.Transpose(.Range("A1").Resize(2).Value)   strKey = Join(strKey, "")  End With    If Trim(strKey) = "" Then MsgBox "検索キーが空です", vbCritical: Exit Sub      With Ws1   Set rng1 = .Range("K2", .Cells(Rows.Count, "K").End(xlUp))   For Each c In rng1.Offset(, -10)     'D,E,F,G,H,I,Kを検索    s = c.Offset(0, 3).Value & c.Offset(0, 4).Value & c.Offset(0, 5).Value & c.Offset(0, 6).Value & c.Offset(0, 7).Value & c.Offset(0, 8).Value & c.Offset(0, 10).Value &        If StrComp(s, strKey, vbTextCompare) = 0 And c.Offset(0, 2).Value = "" Then     c.End(xlToRight).Activate c.Offset(0, 2).Value = Date          c.Resize(1, 14).Interior.ColorIndex = 6     bln = True     Exit For    End If   Next c      If Not bln Then    Ws2.Select    MsgBox "リストに存在しません", vbExclamation, "NotFound"   Else '加える    Call ReSearch(Ws1.Range("M2"), c.Row)    '再設定    Set rng1 = .Range("K6", .Cells(Rows.Count, "K").End(xlUp))    MsgBox "残り" & DoubleCountBlank(rng1.Offset(, -8), rng1) & "品目です。", vbInformation   End If  End With  Application.Goto Ws2.Range("A1"), True End Sub Sub ReSearch(Rng As Range, j As Long) '最初のセル, 終わりの行数 Dim i As Long Dim Ws As Worksheet With Rng.Parent For i = j To Rng.Row Step -1 If CStr(.Cells(i, Rng.Column).Value) Like "191000####" Then MsgBox "指図番号 " & vbCrLf & CStr(.Cells(i, Rng.Column).Value) & " の部品です" Exit For End If Next i End With End Sub Function DoubleCountBlank(rng1 As Range, rng2 As Range) '横並びのセルのブランクをカウントする (セル範囲1 , セル範囲2)  Dim i As Long  Dim cnt As Long  For i = 1 To rng1.Rows.Count   If VarType(rng2.Cells(i, 1)) = vbDouble Then    If rng1.Cells(i, 1).Value = "" And rng2.Cells(i, 1).Value <> 0 Then     cnt = cnt + 1    End If   End If  Next i  DoubleCountBlank = cnt End Function 宜しくお願い致します。

  • 文字変換マクロについて

    数値を文字列に変換するマクロで、行数や列数が増えても対応できるようにしたいです。 (並びは…数値 スペース 文字列)どなたか教えてください。 よろしくお願いします。 Sub 文字() Dim i As Long For i = 1 To Range("A1").End(xlDown).Row Cells(i, "C") = Cells(i, "A") With Cells(i, "C") .NumberFormatLocal = "@" .Value = StrConv(Cells(i, "C").Value, vbNarrow) .Value = Format(Cells(i, "C").Value, "'00") End With Next i End Sub

  • エクセルのマクロについて

    Sub ア_Click() Dim i As Long With ActiveSheet For i = 5 To .Cells(Rows.count, "C").End(xlUp).Row If InStr(.Cells(i, "C"), "ア") = 0 Then If InStr(.Cells(i, "D"), "ア(半角)") = 0 and .Cells(i,"D")<>"" Then MsgBox i & "行目" Cells(i, 2).Offset(0, -1).Value = "★" End If End If Next i End With End Sub このエクセルマクロはC列に「ア」があって、D列に「ア(半角)」の文字がない場合はメッセージというマクロなのですが、このマクロをア~ンまで同じ作業をしたいのですが、ひとまとめにマクロを組む事はできるのでしょうか?できる場合どのようにすれば良いでしょうか? 下記のようにして見たのですができませんでした。 Sub ア_Click() Dim i As Long With ActiveSheet For i = 5 To .Cells(Rows.count, "C").End(xlUp).Row If InStr(.Cells(i, "C"), "[ア-ン]") = 0 Then If InStr(.Cells(i, "D"), "[ア-ン](半角)") = 0 and .Cells(i,"D")<>"" Then MsgBox i & "行目" Cells(i, 2).Offset(0, -1).Value = "★" End If End If Next i End With End Sub

  • エクセル マクロ 教えてください。

    sheet1に (a1=No. b1=月日 C1=項目 d1=収入 e1=支出 f1=摘要 G1=店名)項目を作りそれらをユーザーフォームを作り入力したいです。 この記述では上手く動けません。教えてください。 Private Sub CommandButton1_Click() Dim r As Long, 最終行 As Long, 項目行 As Long Dim re As String r = textboxs1.Value + 10 最終行 = Worksheets("入力").Range("B65536").End(xlUp).Row If r <= 最終行 Then re = MsgBox("訂正" & " " & "すでにデータが入力されています。" & Chr(13) & _ Chr(13) & "データを置き換えます。 本当に良いですか? ", _ Buttons:=vbYesNo + vbExclamation, Title:="注意!!") If re = vbYes Then With Worksheets("入力") .Cells(r, 2).Activate .Cells(r, 1).Value = TBox1.Value .Cells(r, 2).Value = TBox2.Value .Cells(r, 3).Value = ComboBox1.Value .Cells(r, 4).Value = TBox3.Value .Cells(r, 5).Value = TBox4.Value .Cells(r, 6).Value = TBox5.Value .Cells(r, 7).Value = ComboBox2.Value End With データクリア Exit Sub End If データクリア Exit Sub End If If r >= 最終行 + 1 Then r = 最終行 + 1 End If With Worksheets("入力") .Cells(r, 1).Value = TBox1.Value .Cells(r, 2).Value = TBox2.Value .Cells(r, 3).Value = ComboBox1.Value .Cells(r, 4).Value = TBox3.Value .Cells(r, 5).Value = TBox4.Value .Cells(r, 6).Value = TBox5.Value .Cells(r, 7).Value = CBomboox2.Value End With データクリア End Sub r = データNo + 10 With Worksheets("入力") .Activate .Cells(r, 2).Select TBox1.Value = .Cells(r, 1).Value TBox2.Value = .Cells(r, 2).Value ComboBox1.Value = .Cells(r, 3).Value TBox3.Value = Format(.Cells(r, 4).Value, "###,###") TBox4.Value = Format(.Cells(r, 5).Value, "###,###") TBox5.Value = .Cells(r, 6).Value ComboBox2.Value = .Cells(r, 7).Value End With Exit Sub End If If データNo > 最終行 - 10 Then データNo = 最終行 - 9 TBoxNo.Value = データNo データクリア End If End Sub

  • エクセル2003のマクロが2010で使えない

    PC買い換えで、今まで使えていたマクロに下記のようなメッセージが表示されて 使えなくなりました。他人が作成したマクロでまた、私はVBAに詳しくありません。 !はこのマシンで利用できないため、オブジェクトをこのマシンで読み込めませんでした。 コンパイルエラー 変数が定義されていません。 以下記述の一部です。 Private Sub UserForm_Initialize()                    ←ここが黄色に Dim c As Control, i As Integer, j As Integer With data i = 1 Do Until .Cells(i + 1, 1).Value = "" i = i + 1 list01.AddItem .Cells(i, 2).Value For j = 1 To 6 list01.List(i - 2, j) = .Cells(i, j + 2).Value Next j list01.List(i - 2, 7) = .Cells(i, 1).Value Loop i = 1 Do Until .Cells(i + 1, 29).Value = "" i = i + 1 comb02.AddItem .Cells(i, 29).Value comb02.List(i - 2, 1) = .Cells(i, 30).Value comb02.List(i - 2, 2) = .Cells(i, 31).Value comb02.List(i - 2, 3) = .Cells(i, 32).Value comb02.List(i - 2, 4) = .Cells(i, 33).Value comb02.List(i - 2, 5) = Mid(.Cells(i, 29).Value, Len(.Cells(i, 29).Value) - 4, 2) comb02.List(i - 2, 6) = Right(.Cells(i, 29).Value, 2) Loop i = 1 Do Until .Cells(i + 1, 37).Value = "" i = i + 1 comb01.AddItem .Cells(i, 37).Value Loop cal01.Value = .Cells(2, 23).Value                   ← cal01が青く ymdStart = .Cells(2, 26).Value ymdEnd = .Cells(3, 26).Value Controls("opt0" & .Cells(3, 23)).Value = True chk01.Value = .Cells(4, 23).Value For Each c In Controls If Left(c.Name, 4) = "list" Or Left(c.Name, 4) = "text" Or Left(c.Name, 4) = "comb" Then c.ForeColor = .Cells(13, 25).Value c.BackColor = .Cells(16, 25).Value End If Next c End With With list01 If .ListCount = 0 Then If MsgBox("職員が登録されていません。", 48, ThisWorkbook.Name) = 1 Then End If Else ReDim GroupTable(.ListCount - 1, 1) i = 0 For j = 0 To .ListCount - 1 If .List(i, 0) <> .List(j, 0) Then i = j End If GroupTable(j, 0) = i Next j i = .ListCount - 1 For j = .ListCount - 1 To 0 Step -1 If .List(i, 0) <> .List(j, 0) Then i = j End If GroupTable(j, 1) = i Next j End If End With but07.ControlTipText = ThisWorkbook.Name & "の上書き保存" MsgMode = True Call cal01_Click Call opt04to05_Change End Sub どうしていいかわかりませんので、よろしくお願いします。 Windows7 Professional SP1 64

専門家に質問してみよう