• ベストアンサー

配列処理を遅くてもよいので軽い処理に変えたい。

end-uの回答

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

Excelのバージョンは何ですか? 一応、違うアプローチで以下のようなものが考えられますが Sub try()   Dim NEWBOOK As Workbook   Dim OLDBOOK As Workbook   Dim wb   As Workbook   Dim sh   As Object   Dim dic   As Object   Dim i    As Long   Dim oldname As String   Dim iOldCalculation As Long   '現在の再計算モードの取得   iOldCalculation = Application.Calculation   '再計算モードを手動に設定   Application.Calculation = xlManual   'Set OLDBOOK = Workbooks("oldbook.xls")   'Set NEWBOOK = Workbooks("newbook.xls")   'OLDBOOKシート名をdictionaryに登録   Set dic = CreateObject("scripting.dictionary")   For Each sh In OLDBOOK.Sheets     dic(sh.Name) = Empty   Next   '新規Bookを追加   Set wb = Workbooks.Add(xlWBATWorksheet)   wb.Sheets(1).Name = "dummy"      'NEWBOOKのシートをLoopして名前がdictionaryにあれば OLDBOOKから _    なければ NEWBOOKから新規Bookに移動する。   With NEWBOOK     For i = .Sheets.Count To 1 Step -1       With .Sheets(i)         If dic.exists(.Name) Then           OLDBOOK.Sheets(.Name).Move before:=wb.Sheets(1)         Else           .Move before:=wb.Sheets(1)         End If       End With     Next   End With      oldname = OLDBOOK.FullName   OLDBOOK.Close False        '保存せず閉じる   NEWBOOK.Close False        '保存せず閉じる      Application.DisplayAlerts = False   wb.Sheets("dummy").Delete     'wbの初期シートを削除   'wb.SaveAs oldname         'OLDBOOK.FullNameで強制上書き保存   Application.DisplayAlerts = True   '再計算モードの復元   Application.Calculation = iOldCalculation   Set dic = Nothing   Set NEWBOOK = Nothing   Set OLDBOOK = Nothing   Set wb = Nothing End Sub >シートは関数などがぎっしり書き込まれているので、重いものなのです。 >それをBOOKに出来れば100枚位まで入るようにしたいのです。 という仕様に無理があるのかもしれませんね。

yokokama46
質問者

お礼

end-uさんへ 今拝見しました。 今から明日まで出張のため、非常に残念ながら、即、検証出来ませんが、明日の夜には戻るので、明後日までには必ず検証して報告致します。 取り急ぎお礼申し上げます。それでは。

yokokama46
質問者

補足

昨日まで出張になりまして、返事が遅くなりました。すいません。 検証の結果、今回のきもの部分 If dic.exists(.Name) Thenの判定及びそれ以下のそれぞれの処理OKです。(問題はCopy Afterで重いシートを大量に貼り付けることにあり)有難うございます。 CreateObjectは使ったことがありませんでした。なるほどそういうのもありかと思った次第です。感謝です。発想が膨らみました。そこで今回取り上げた以外のもので、作成する予定のリストを連想配列(1行に4列で(名前がKeyで他3つのItems)2行目から100行位まで)と作成済みのファイルから差分を求めて、以下処理するという勉強をしたいと思いました。今回は、助かりました。よく行き詰るのでその際は、またお知恵を貸して下さい。

関連するQ&A

  • EXCEL2007ではOKですが2003だとエラーになる

    よろしくお願いします。 下記のコード(抜粋)がエクセル2007では全く問題なく動くのに、2003だとエラーになってしまうというもので困ってしまいました。 下記は二つのファイルの構成を比較して(OLDBOOKのシートをNEWBOOKと同じ構成にする)追加、削除、並び替えを行うというものです。 残念ながら、当方2003を持ってないので確認が出来ません。(当然配布は互換形式) 各配布先で試してもらったところ、2007のところは問題なし。2003のところはすべてエラーとなり、エラー箇所は抜粋している範囲のさらに2つのファイルを比較し、必要に応じて追加、削除を行う部分です。 Set shDst = OLDBOOK.Sheets(shSrc.Name) と Set shSrc = NEWBOOK.Sheets(shDst.Name) の部分で「454のオブジェクトエラー」となるとのことでした。原因は、そこにあると思いましたが、2007では問題ないので、何が悪いのかさっぱりです。どなたか助けて下さい。 Dim FIRSTBOOK As Workbook Dim OLDBOOK As Workbook Dim shSrc As Object Dim shDst As Object ~省略 ~ '現在の再計算モードの取得 iOldCalculation = Application.Calculation '再計算モードを手動に設定 Application.Calculation = xlManual '*****ここから比較***** ' // まず NEWBOOK.xls にあって OLDBOOK.xls にないシートをOLDBOOK.xls に複写 For Each shSrc In NEWBOOK.Sheets On Error Resume Next Set shDst = OLDBOOK.Sheets(shSrc.Name) On Error GoTo 0 If shDst Is Nothing Then shSrc.Copy After:=OLDBOOK.Sheets(OLDBOOK.Sheets.Count) End If Set shDst = Nothing Next ' // 続いてNEWBOOK.xls になくてOLDBOOK.xls にあるシートをOLDBOOK.xls から削除 For Each shDst In OLDBOOK.Sheets On Error Resume Next Set shSrc = NEWBOOK.Sheets(shDst.Name) On Error GoTo 0 If shSrc Is Nothing Then shDst.Delete End If Set shSrc = Nothing Next ' // シート並べ替え For Each shDst In OLDBOOK.Sheets shDst.Move Before:=OLDBOOK.Sheets(NEWBOOK.Sheets(shDst.Name).Index) shDst.Protect DrawingObjects:=True, Contents:=True, UserInterfaceOnly:=True Next '再計算モードの復元 Application.Calculation = iOldCalculation NEWBOOK.Close (False) '有無を言わずに保存せず閉じる ~省略 ~

  • 追加の質問ですが、シートを一致させたい。

     昨日の質問(シートを配列に格納して比較)で解決したのですが、 欲が出てきました。前回は、NEWBOOKにあってOLDBOOKにないものを NEWBOOKからOLDBOOKに挿入し、OLDBOOKをNEWBOOKと同じく並び換えるという流れでした。(Ken-KenSPさんありがとう御座いました。)  今回は、更にNEWBOOKにないものをOLDBOOKから削除もしたいので、  シート追加のコードを逆に検索させ、Deleteにしてみましたが、消えません。よって並び替え時に数が合わないため(シートが合わない)エラーになってしまいます。  目的 OLDBOOKをNEWBOOKのシート構成と同じにするために(単に上書きではなく) NEWBOOKにあってOLDBOOKにないシートはNEWBOOKからOLDBOOKに挿入 OLDBOOKにあってNEWBOOKにないシートはOLDBOOKから削除 設定 NEWBOOKはコピー元 OLDBOOKはコピー先 shSrcはNEWBOOK内のシート shDstOLDBOOK内のシート ' // まず NEWBOOK.xls にあって OLDBOOK.xls にないシートを複写   For Each shSrc In wbSrc.Sheets     On Error Resume Next     Set shDst = wbDst.Sheets(shSrc.Name)     On Error GoTo 0     If shDst Is Nothing Then       shSrc.Copy After:=wbDst.Sheets(wbDst.Sheets.Count)     End If     Set shDst = Nothing    Next ' // 続いてOLDBOOK.xls にあって NEWBOOK.xls にないシートを削除 For Each shDst In OLDBOOK.Sheets On Error Resume Next Set shSrc = NEWBOOK.Sheets(shDst.Name) On Error GoTo 0 If shDst Is Nothing Then shDst.Delete End If Set shSrc = Nothing ' <---- 追加 Next   ' // シート並べ替え   For Each shDst In wbDst.Sheets     shDst.Move Before:=wbDst.Sheets(wbSrc.Sheets(shDst.Name).Index)   Next 上記のコードのDeleteのコードの変数の入れ方(元、先)があやしい以外はなさそうなので、試しましたが、やっぱり助けて下さい。

  • 保護されたブックのコピーについて

    現在、ボタンを押すと新規ブックが作成され、最初のブックのシートをコピーするというマクロを組みました。 しかし、元になるブックにはブックの保護とシートの保護を両方かけていて、途中でエラーになるはずなのですが、何故かそうならずに普通に新規ブックにコピーがされます。 上手くいったのですがエラーが出ると予想していたので気持ちが悪く、また個人だけで使うわけじゃないので原因を知っておきたいです。 どなたかよろしくお願いします。 Private Sub makeBookButton_Click() Dim myWorkBook As String Dim newWorkBook As String Dim mySheet As Worksheet Application.ScreenUpdating = False On Error GoTo ErrTrap Application.DisplayAlerts = False myWorkBook = ThisWorkbook.Name Workbooks.Add ActiveWorkbook.SaveAs Filename:=NEWBOOK newWorkBook = ActiveWorkbook.Name Workbooks(myWorkBook).Activate For Each mySheet In ThisWorkbook.Worksheets Workbooks(myWorkBook).Sheets(mySheet.Name).copy after:=Workbooks(newWorkBook).Sheets(Workbooks(newWorkBook).Sheets.Count) Next Workbooks(NEWBOOK).Sheets("Sheet1").Delete Workbooks(NEWBOOK).Sheets("Sheet2").Delete Workbooks(NEWBOOK).Sheets("Sheet3").Delete Application.DisplayAlerts = True Application.ScreenUpdating = True Exit Sub ErrTrap: Call MsgBox("ブック作成時にエラーが発生しました。", vbCritical) End Sub

  • VBAであるBOOKの「sample」というシートを別BOOKに

    VBAであるBOOKの「sample」というシートを別BOOKに 別Bookにコピーしたいのですが、 ネットを参考にして下記のようにするとエラーになります。 実行時エラー'9' 「インデックスが有効範囲にありません」 と表示されます。 どこが間違っているでしょうか? どなたか教えてください。 ---------------------------------------- Dim NewBook As Workbook Dim fName As String Set NewBook = Workbooks.Add fName = ThisWorkbook.Path & "cp.xls" NewBook.SaveAs Filename:=fName Workbooks("moto.xls").Sheets("ピッキング").Cells.Copy Workbooks(fName).Sheets("Sheet1").Paste Destination:=Cells(1, 1) '<---ここでエラー Workbooks(fName).Save ----------------------------------------

  • マクロでファイル名を指定して保存する際にエラー

    「全データ」というシートをマクロでファイル名に「伝票+実行時の日付・時間]をいれてCSV形式で保存したいと思い、 一度マクロを登録してみたのですが、途中でエラーが発生しうまくいきません。 「"」や「&」の付け方に問題があるかと思い、いろいろなパターンで試しましたが同様です。 修正記述がお分かりの方がいらっしゃいましたら、お言葉をいただけると幸いです。 宜しくお願いいたします。 ------------------------------------------------------------------------------------- Sheets("全データ").Select Dim file As Variant Dim NewBook As Workbook Dim NowSheet As Worksheet Set NowSheet = ActiveSheet file = Application.GetSaveAsFilename("伝票" & Now, "yy-mm-dd-hh-mm" & ".csv", "CSVカンマ区切り形式 (*.csv), *.csv") If file = False Then Exit Sub  ←ここでエラー2015が発生 Set NewBook = Workbooks.Add NowSheet.Copy before:=NewBook.Worksheets(1) On Error Resume Next NewBook.Worksheets(1).SaveAs Filename:=file, FileFormat:=xlCSV On Error GoTo 0 Application.DisplayAlerts = False NewBook.Close Application.DisplayAlerts = True NowSheet.Activate   End Sub

  • TextToDisplayがうまく出来ない。

    シートの中の全てのハイパーリンクのアドレスとテキストを新シートに一覧で書き出すマクロを作ってるのですが、詰みました。 例えば、http://oshiete.goo.ne.jp/をctrl+A→ctrl+Cで、全体をコピーして エクセルのシートに貼り付けます。(添付画像参照) そうした状態で、 ///////////////////////////////////////////////////////// Sub test() Dim h As Hyperlink Dim MyRow As Long Dim StrURL As String Dim StrTEXT As String Dim MyBook As Workbook Dim NewBook As Workbook Debug.Print ActiveSheet.Hyperlinks.Count Set MyBook = ActiveWorkbook Set NewBook = Workbooks.Add 'ブックを挿入したらアクティブになってしまう MyRow = 1 For Each h In MyBook.ActiveSheet.Hyperlinks StrURL = h.Address 'アドレスを抜き出す If IsNull(h.TextToDisplay) = True Then StrTEXT = "" Else StrTEXT = h.TextToDisplay '表示文字を抜き出す End If NewBook.Activate '新ブックをアクティブにする Cells(MyRow, 1) = StrURL Cells(MyRow, 2) = StrTEXT MyRow = MyRow + 1 Next Set MyBook = Nothing Set NewBook = Nothing End Sub ///////////////////////////////////////////////////////// を実行してるのですが、h.TextToDisplayが空白の時?値がエラーの時?に、 実行時エラー ’-2147467259(800004005)': 'TextToDisplay'メソッドは失敗しました:'Hyperlink'オブジェクト となってしまいます。 If IsNull(h.TextToDisplay) = True Then をすれば回避できると思いましたが、ダメでした。 なんでこのエラーになるのかと、このエラーを回避する方法を教えてください。 ご回答よろしくお願いします。

  • ブック全体の検索の次へは?

    ブック全体を検索するマクロ作ったのですが、 ブックの最初にあるものしか見つけられません。 見つかった時に、次の検索を行うにはどのようなVBAになるのでしょうか? よろしくお願いもうしあげます。 Sub KensakuAll() 'ブック内の全シートを検索   Dim myWb As Workbook   Dim mySht As Worksheet   Dim myRng As Range   Dim Key1 As String   Key1 = InputBox("検索キーを入力しなさい")   If Key1 = "" Then Exit Sub   For Each mySht In Sheets     Set myRng = mySht.Cells.Find(what:=Key1)     If Not myRng Is Nothing Then       mySht.Activate       myRng.Activate       Set mySht = Nothing       Set myRng = Nothing       Exit Sub     End If   Next   MsgBox "該当するセルは見つかりませんでした"   Set mySht = Nothing   Set myRng = Nothing End Sub

  • EXCELの配列で

    メールの本文を1行づつよみとってEXCELへ書き出そうと思っています。 Sub getMail1() Dim myOl As New Outlook.Application Dim dFolder As MAPIFolder Dim myItem As MailItem Dim delItem As MailItem Dim myRecipient As Recipient Dim i As Long, j As Long Const mAddress = 0, mTel = 1, mName = 2, mAge = 3 Set dFolder = myOl.GetNamespace _ ("MAPI").Folders("個人用フォルダ").Folders("単発") i = 1 On Error Resume Next For Each myItem In dFolder.Items i = i + 1 Set delItem = myItem.Reply For Each myRecipient In delItem.Recipients If InStr(1, myRecipient.Address, "@", vbBinaryCompare) _ <> 0 Then Exit For End If Next delItem.Delete With ActiveSheet myBody = Split(myItem.Body, vbCrLf) .Cells(i, 1).Value = myRecipient.Address .Cells(i, 2) = myItem.SenderName .Cells(i, 3) = myItem.Subject .Cells(i, 4) = myItem.ReceivedTime For j = 0 To UBound(myBody) i = i + 1 On Error Resume Next .Cells(i, 1) = myBody(j) .Cells(i, 1).MergeCells = True Next End With i = i + 1 Next Set myOl = Nothing End Sub このようなコードを書いて書き出すことは出来たのですが配列が縦になってしまいます。 横に配列したいのですが教えてください。 伊藤太郎 東京都 03-3123-4567を 伊藤太郎 東京都 03-3123-4567 としたいです。 よろしくお願いします。

  • Matchの処理について

    下記の処理がどうしてもうまくいかなくて、 皆様のお知恵を拝借できればありがたいです。 Sheet1に下記のように縦に3列データがならんでいます。 A  あ  10 A  い  12 A  う  16 B  あ  19 B  い  15 B  う   7 これをもとにSheet2に下記の通りマトリクス形式に 変換する。   あ  い  う A  10  12  16 B  19  15   7 これを処理しようと以下の通り記述したのですが、 マッチする項目がなかった場合、どうも行(列)が ずれてヒットしているようです。 On Error Resume Nextが原因のような気がするのですが。 これを回避するにはどうしたらよろしいでしょうか? お助けください~。 よろしくお願い致します。 Dim i As Long Dim j As Long Dim k As Long Dim 検索値A As Variant Dim 検索値B As Variant On Error Resume Next i = 2 Do While (Sheets("SHEET1").Cells(i, 1) <> "") 検索値A = Sheets("SHEET1").Cells(i, 1).Value 検索値B = Sheets("SHEET1").Cells(i, 2).Value j = Application.Match(検索値A, Sheets("Sheet2").Range("範囲A"), 0) k = Application.Match(検索値B, Sheets("Sheet2").Range("範囲B"), 0) Sheets("Sheet2").Cells(j, k).Value =Sheets("SHEET1").Cells(i, 3) i = i + 1 Loop End Sub

  • 図形のクリアで実行時の1004エラーになる

     指定範囲(I9:CW40)から図形(円・四角形)のクリアをするとエラーになってしまいます。終了をすればクリアはできるのですが。御教授願えませんでしようか?(尚四角形はセルの枠線上に貼り付けるようにしてあります。) Sub 図形のクリア() Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Dim myRng As Range Dim sp As Variant Set myRng = Range("I9:CW40") For Each sp In ActiveSheet.Shapes If Not Intersect(Range(sp.TopLeftCell, sp.BottomRightCell), myRng) Is Nothing Then sp.Delete (ここで実行時1004のエラーになる。) End If Next Set myRng = Nothing Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic End Sub