[[20101130133022]] 『違うブックから、データを抽出』(マル) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『違うブックから、データを抽出』(マル)
 excel2002

 何度も恐れ入ります。

 1_8_(2010年10月)Rev_01Bookの(書き出し元ブック)、1_10月 (2)sheetのC2:C25の数値を、
 マクロBook(書き出し先シート)、主sheetのB2:B25に抽出して貼り付けをしたいです。

 Sub データ抽出()

 Dim writeSheet As Worksheet ' 書き出し先シート
 Set writeSheet = ThisWorkbook.Worksheets("主sheet") ' 主sheet を参照

 Dim readBook As Workbook ' 書き出し元ブック
 Set readBook = Workbooks.Open("1_8_(2010年10月)Rev_01") ' 書き出し元ブックを開いて参照
 Dim readSheet As Worksheet ' 書き出し元シート
 Set readSheet = readBook.Worksheets("1_10月 (2)") ' 書き出し元シートを参照

 writeSheet.Range("B2:B25").Value = readSheet.Range("C2:C25").Value
 ' 書き出し元シートの C2:C25 の値を、書き出し先のB2:B25に書き込む

 readBook.Close False ' 書き出し元ブックを閉じる
 Set readSheet = Nothing
 Set readBook = Nothing

 End Sub

 Set writeSheet = ThisWorkbook.Worksheets("主sheet") ' 主sheet を参照で
 インデックスが有効範囲にありませんとエラーがでます。

 マクロは、自分で作成した事がなく、
 色々と調べて調べて作ってみたのですが、
 どこをどのように修正すれば、
 うまく動作するのか、ご指導をお願いできますでしょうか?

 書き出し元ブックは、初めから開いておいた方が、簡単なマクロで出来るのでしょうか?
 
 全く検討違いなマクロになっているかと思いますが、
 よろしくお願いいたします。

 インデックスが有効範囲にありませんのエラー自体はそのシート名が存在しない。
 という事ですので半角スペースがあったりとか実際に同じかどうか確かめてみましょう。

 あと、Workbooks.Openのブックの部分はフルパスにしてくださいね。
 (momo)

momoさま
 アドバイス 有難うございました!
 おかげさまで、マクロが動きました。

 Sub データ抽出()

 Dim writeSheet As Worksheet ' 抽出先シート
 Set writeSheet = ThisWorkbook.Worksheets("抽出先シート") ' 抽出先シートを参照

 Dim readBook As Workbook ' 参照先ブック
 Set readBook = Workbooks.Open("C:\Documents and Settings\Administrator\デスクトップ\マクロ勉強\参照先") ' 参照先ブックを開いて参照
 Dim readSheet As Worksheet ' 参照先シート
 Set readSheet = readBook.Worksheets("参照先シート") ' 参照先シートを参照

 writeSheet.Range("B2:B25").Value = readSheet.Range("C2:C25").Value
  ' 参照先シートの C2:C25 の値を、抽出先のB2:B25に書き込む

 readBook.Close False ' 参照先ブックを閉じる
 Set readSheet = Nothing
 Set readBook = Nothing

 End Sub

 また、先ほどのマクロをどのように運用すれば良いのか、教えていただけますでしょうか?
 下記の作業をしたいのですが、シート1からシート27に一回でデータを反映するには、
 どのようにすれば良いのでしょうか?
 先ほどのマクロは、標準モジュールに作成したのですが、
 下記のように、シートの名前が違う場合は、どのように対応すれば良いのでしょうか?
 また、下記のような条件のマクロは、どのように作成すれば良いのでしょうか?
 ひとつひとつ手で、上記のマクロを作るのでしょうか?

 抽出先Book:抽出先のシートsheet1〜sheet27
 B2:B25、C2:C25・・・AF2:AF25に、
 全シート同じフォーマットです。参照先からの抽出データを入力したい。
           

 参照先Book:参照先シート
 C2:C25、C28:C51・・・ C782:C805 このデータを抽出先ブックのシート1のB2:B25、C2:C25・・・AF2:AF25に貼り付けしたい。
 同様に、抽出先ブックのシート2には、
 D2:D25、D28:D51・・・ D782:D805
 同様に、抽出先ブックのシート27には、
 AC2:AC25、AC28:D51・・・ AC782:AC805

 解りにくい説明で恐れ入りますが、教えていただけますでしょうか?
 よろしくお願いいたします。(マル)

 それですと、ループ処理にしなければなりませんね。
 私なりの書き方でサンプルを書いてみましたので参考にして
 ヘルプなどで調べてみてください。

  Sub データ抽出()
  Dim tbl As Variant, i As Long, j As Long
  Dim mySheet As Worksheet
  Dim dat(1 To 26, 1 To 31)

  With Workbooks.Open("C:\Documents and Settings\Administrator\デスクトップ\マクロ勉強\参照先.xls")
    tbl = .Worksheets("参照先シート").Range("C2:AC805").Value
    .Close False
  End With
  For i = 1 To 27
    For j = 1 To 804
      dat((j - 1) Mod 26 + 1, (j - 1) \ 26 + 1) = tbl(j, i)
    Next j
    With ThisWorkbook
      On Error Resume Next
      Set mySheet = .Worksheets("Sheet" & i)
      If Err.Number > 0 Then
        Set mySheet = .Worksheets.Add(After:=.Worksheets(.Worksheets.Count))
        mySheet.Name = "Sheet" & i
      End If
      On Error GoTo 0
      mySheet.Range("B2:AF25").Value = dat
    End With
    Erase dat
  Next i
  End Sub

 (momo)

 momoさま
 いつもありがとうございます!

 おかげさまで、一気に入力できました!

 説明不足で申し訳ありません。

 実行したところ、新しくシートが追加されますが、
 すでに、抽出先のブックには、sheet1〜sheet27にそれぞれ別の名前のシートがあり、
 書式だけ設定されており、後は、数値を抽出するだけの状態になっているのですが、
 新しいシートを作成せずに、すでに作成済みの左から1つ目のシートから、27つ目のシートに、
 上記のマクロを反映する事は、可能なのでしょうか?
 Sheets.Selectを使うのか?と思ったりしたのですが、どこをどうすれば良いのか、
 勉強不足のため、出来ませんでした。教えて頂いた式は、ヘルプで勉強してみます。
 お手数をお掛けしますが、何か良い方法がありましたら、再度教えていただけますでしょうか?
 よろしくお願いいたします。(マル)


 シートが必ずある。という条件のもとでしたら

  Dim mySheet As Worksheet

 の1行を消して

      On Error Resume Next
      Set mySheet = .Worksheets("Sheet" & i)
      If Err.Number > 0 Then
        Set mySheet = .Worksheets.Add(After:=.Worksheets(.Worksheets.Count))
        mySheet.Name = "Sheet" & i
      End If
      On Error GoTo 0
      mySheet.Range("B2:AF25").Value = dat

 の部分を

    .Worksheets(i).Range("B2:AF25").Value = dat

 だけにしてみてください。
 (momo)

 momoさま
 ご丁寧に有難うございました!
 思っていた通りに出来ました。

 全然知識がないのですが、マクロを使用する事が多くなりました。
 勉強を始めたのですが、なかなか思うように出来ずに、
 困っていたので、大変助かりました。
 教えて頂いたマクロを、時間が出来たら、しっかり勉強したいと思います。
 有難うございました!(マル)


 いつもお世話になっております。
 先日教えて頂いた件で、再度ご教授をお願いできますでしょうか?

 参照先のシートの列が1列増えたので、下記のように変更しました。
 抽出先のシートも1枚増えました。
 既存の抽出先のシート28枚に、参照先のデータを抽出したいです。
 参照先のデータが1列増え、C2:AD805が参照範囲になりました。

 dat((j - 1) Mod 26 + 1, (j - 1) \ 26 + 1) = tbl(j, i)の部分の式を、
 dat((j - 1) Mod 27 + 1, (j - 1) \ 27 + 1) = tbl(j, i)に変更すると、
 違うデータが表示されていたので、ここは、変更しないまま、
 下記のマクロを実行したのですが、
 dat((j - 1) Mod 26 + 1, (j - 1) \ 26 + 1) = tbl(j, i)は、変更しなくて、
 式は間違えていないのでしょうか?この部分の意味も、
 できましたら、教えていただけないでしょうか?
 

 Option Explicit

 Sub データ抽出()
  Dim tbl As Variant, i As Long, j As Long
  Dim dat(1 To 27, 1 To 31)'抽出先のsheetが1枚増えたので、1 To 26を、1 To 27に変更。

  With Workbooks.Open("C:\Documents and Settings\Administrator\デスクトップ\マクロ勉強中\参照先.xls")
    tbl = .Worksheets("参照先シート").Range("C2:AD805").Value’参照先の列が1列増えたので、ACをADに変更
    .Close False
  End With
  For i = 1 To 28'抽出先のsheetが1枚増えたので、1 To 27を 1 To 28に変更
    For j = 1 To 804
      dat((j - 1) Mod 26 + 1, (j - 1) \ 26 + 1) = tbl(j, i)
    Next j
    With ThisWorkbook
      .Worksheets(i).Range("B2:AF25").Value = dat

    End With
    Erase dat
  Next i
  End Sub

 何度も恐縮ですが、教えていただけますでしょうか?
 よろしくお願いいたします。(マル)

 > Dim dat(1 To 27, 1 To 31)'抽出先のsheetが1枚増えたので、1 To 26を、1 To 27に変更。
 ここは変更しないで良いはずです。
 26のままで。

 >   tbl = .Worksheets("参照先シート").Range("C2:AD805").Value’参照先の列が1列増えたので、ACをADに変更
 これはOK

 > For i = 1 To 28'抽出先のsheetが1枚増えたので、1 To 27を 1 To 28に変更
 これもOK

 >dat((j - 1) Mod 26 + 1, (j - 1) \ 26 + 1) = tbl(j, i)
 これについては
 元のシートの1列の行数から2次元の配列へ転記するための座標を作っています。
 行番号から2次元へなので、列が増えただけであれば変更はいらないはずです。

 で、たとえば新規のブックで

 for j=1 to 804
  cells(j+1,1).value=j
   cells(j+1,2).value=(j-1) mod 26+1
   cells(j+1,3).value=(j-1)\26+1
 next j
 range("A1:C1").value=array("参照先の行番号","抽出先の行","抽出先の列")

 なんていうコードを走らせてみると
 参照先の範囲内の行番号と、抽出先の範囲の行列番号との関係がわかると思います。

 (momo)

 momoさま
 いつも有難うございます!
 おかげさまで、出来ました!

 教えていただいた、例題が、とても、わかりやすそうなので、
 新規ブックで勉強してみます。

 ご丁寧に教えてくださり、有難うございました!(マル)

 何度も申し訳ありません。教えていただいた事を読んで、
 理解しようとしたのですが、まだ理解できず、再度、教えていただけないでしょうか?

 momoさんが参考に教えてくださった、コードを走らせてみて、動きは、大変よくわかったのですが、
 数値の設定の仕方が、まだ理解できず、検討違いな質問になっているかもしれませんが、よろしくお願いいたします。

 Dim dat(1 To 26, 1 To 31)
 この26は、参照先シートのC2:C25や、D2:D25の行数から来ているのでしょうか?
 C1に項目行、C26は空白となっており、データ数を実際数えてみると24なのですが、
 C1に項目行、C26は空白行を含めて、C1から、C26の処理を、行うため、26となるのでしょうか?
 項目、空白のセルを含めて、毎回繰り返しを26行ずつすると言う、認識で合っているのでしょうか?
 思っているとおりの処理が行われているのですが、
 この項目や、空白も一緒に処理した場合、この項目と空白は、どこに行くのだろう?と思ったりしました。
 また、1 To 31は、抽出先のシートのB2:B25、C2:C25・・・AF2:AF25に貼り付けるための数値なのでしょうか?
 この31がどこから来る数字なのか、教えていただけないでしょうか?

 丁寧に教えていただいているのに、何回も質問してしまい、申し訳ありません(マル)


 >C1に項目行、C26は空白行を含めて、C1から、C26の処理を、行うため、26となるのでしょうか?
 こっちの考え方が近いですが微妙に違います。

 参照先が C2:C25、C28:C51・・・ とあるので
 一区切りの先頭はC2、C28・・・と26行ごとですよね?

 エリアを限定してStepでも処理できますが、面倒なのでそのまま同じ処理をしてしまえっ><
 というだけです。
 (厳密に処理時間をミリ秒単位で早くしたければダメですが)

 >項目、空白のセルを含めて、毎回繰り返しを26行ずつすると言う、認識で合っているのでしょうか?
 という事に近いです。

 >この項目や、空白も一緒に処理した場合、この項目と空白は、どこに行くのだろう?
 どこにも行かずに消えていきます(笑)

 .Worksheets(i).Range("B2:AF25").Value = dat

 ここでシートに転記していますが、 B2:AF25なので24行分しかありません。
 変数datの中身は26行ありますが、転記先の範囲分しか転記しないという特性を使っています。
 なので、どうせ後でシートに書く時に24行分だけすればいいので
 途中のロジックの中で「26行ごとに24行の処理をする」という面倒な事を省略したのです。

 >また、1 To 31は、抽出先のシートのB2:B25、C2:C25・・・AF2:AF25に貼り付けるための数値なのでしょうか?
 >この31がどこから来る数字なのか、教えていただけないでしょうか?
 その通りです。
 単純にB列からAF列までなので31列分という事です。
 こんなコードを新規ブックで試すと解りますか?

  Sub ColumnNum()
  For i = 1 To 31
    Columns("B:AF").Cells(i).Value = i
  Next i
  Columns("B:AF").AutoFit
  End Sub

 >丁寧に教えていただいているのに、何回も質問してしまい、申し訳ありません
 いえいえ、学校ですから本来このようなやりとりが必要だと思います。
 ちゃんと私の書いたことに対して理解しようとしたり、質問して下さるのが嬉しいです。
 頑張ってください。

 (momo)

 momoさま

 いつも有難うございます!
 すごく解りやすいご説明で、やっと理解できました。
 ネットで調べても、つまずいてばかりで、
 こうして教えていただける事、とても感謝しています。
 頑張ってください。>嬉しすぎます。
 関数もマクロも勉強しはじめたばかりで、つまずきっぱなしですが、
 これからも、ご教授、よろしくお願いいたします。
 今回も、ありがとうございました!(マル)


 以前、教えていただいた、下記を再度復習しているのですが、
 何度もお恥ずかしいのですが、また、ご教授をお願いできますでしょうか?

 for j=1 to 804
   cells(j+1,2).value=(j-1) mod 26+1
   cells(j+1,3).value=(j-1)\26+1
 next j

 この式を変更して,
 A列に、1ヶ月分の日付(同じ日付を24個ずつ表示・・・24時間分)
 B列に、1:00〜24:00、を繰り返し31日分まで表示してみたいのですが、
 日付と時間の表示がうまく出来ませんでした。
 A列の日付が、1900/1/1、1900/1/2・・・となり、
 B列の時間が、すべて、0:00と表示されてしまいます。
 (表示形式を、A列が、2011/1/1、B列を、1:00になるように、設定しました。)

 Option Explicit

 Sub test()

 Dim j As Integer
 Dim d As Date
 Dim t As Date

 d = DateValue("2011/1/1")
 Range("A1").Value = d

 t = TimeValue("1:00:00") '午前1時
 Range("B1").Value = t

 For j = 1 To 744
 Cells(j, 1).Value = (j - 1) \ 24 + 1
 Cells(j, 2).Value = (j - 1) Mod 24 + 1

 Next j

 End Sub

 調べてみたのですが、解らず、また相談させていただきました。
 よろしければ、アドバイスをお願いいたします。(マル)

 >Cells(j, 1).Value = (j - 1) \ 24 + 1
 >Cells(j, 2).Value = (j - 1) Mod 24 + 1

 これだと単なる数値データなので
 Date型のdとtという変数が何も意味を成してないですよね?

 あと、日付の加減を少数演算で行うと誤差もありますしお勧めできません。
 DateAddなどを使って確実にした方が良いように思います。

 応用部分はModくらいでしょうか?

 Sub test()
 Dim i As Long
 Dim FirstDate As Date, VarDate As Date
 Dim FirstTime As Date, VarTime As Date
 FirstDate = DateValue("2011/1/1")                '初期日付
 FirstTime = TimeValue("0:00")                    '初期時間
 VarDate = FirstDate                              '可変日付変数に初期日付をセット
 VarTime = FirstTime                              '可変時間変数に初期時間をセット
 While Month(VarDate) = Month(FirstDate)          '初期日付と可変日付の月が同じ間繰り返す
   i = i + 1                                      'カウンタ変数に1を足す
   Cells(i, 1).Value = VarDate                    'A列のi行目に可変日付をセット
   Cells(i, 2).Value = VarTime                    'B列のi行目に可変時間をセット
   VarDate = DateAdd("d", Int(i \ 24), FirstDate) '可変日付にiが24毎に1日を足す
   VarTime = DateAdd("h", i, FirstTime)           '可変時間にi時間を足す
 Wend                                             '繰り返す
 End Sub

 (momo)

 momoさま
 遅くなりましたが、m(__)m
 いつもご親切に、有難うございます!

 詳細の説明も、たいへん、解りやすかったです。

 練習で、For Nextでもできるのかな?と思い、
 してみたら、おかげさまで、思った通りにできました。

 お世話になりました!(マル)

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.