Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


4401 / 13646 ツリー ←次へ | 前へ→

【56864】別シートへ行と列を入れ替えてコピー 初心者さっち 08/7/9(水) 9:11 質問[未読]
【56866】Re:別シートへ行と列を入れ替えてコピー ハチ 08/7/9(水) 9:22 回答[未読]
【56868】Re:別シートへ行と列を入れ替えてコピー 初心者さっち 08/7/9(水) 11:27 質問[未読]
【56869】Re:別シートへ行と列を入れ替えてコピー kanabun 08/7/9(水) 12:02 発言[未読]
【56885】Re:別シートへ行と列を入れ替えてコピー 初心者さっち 08/7/9(水) 16:51 お礼[未読]
【56873】Re:別シートへ行と列を入れ替えてコピー ハチ 08/7/9(水) 13:19 発言[未読]
【56874】Re:別シートへ行と列を入れ替えてコピー ハチ 08/7/9(水) 13:33 発言[未読]
【56883】Re:別シートへ行と列を入れ替えてコピー 初心者さっち 08/7/9(水) 16:48 質問[未読]
【56886】Re:別シートへ行と列を入れ替えてコピー kanabun 08/7/9(水) 17:18 発言[未読]
【56887】Re:別シートへ行と列を入れ替えてコピー ハチ 08/7/9(水) 17:39 発言[未読]
【56888】Re:別シートへ行と列を入れ替えてコピー ハチ 08/7/9(水) 17:54 発言[未読]
【56897】Re:別シートへ行と列を入れ替えてコピー 初心者さっち 08/7/10(木) 9:07 お礼[未読]
【56899】Re:別シートへ行と列を入れ替えてコピー 初心者さっち 08/7/10(木) 10:27 お礼[未読]
【56902】Re:別シートへ行と列を入れ替えてコピー ハチ 08/7/10(木) 11:10 発言[未読]
【56900】Re:別シートへ行と列を入れ替えてコピー kanabun 08/7/10(木) 10:39 発言[未読]
【56901】Re:別シートへ行と列を入れ替えてコピー 初心者さっち 08/7/10(木) 10:56 お礼[未読]
【56904】Re:別シートへ行と列を入れ替えてコピー kanabun 08/7/10(木) 11:22 発言[未読]
【56918】Re:別シートへ行と列を入れ替えてコピー 初心者さっち 08/7/10(木) 16:10 質問[未読]
【56919】Re:別シートへ行と列を入れ替えてコピー kanabun 08/7/10(木) 17:04 発言[未読]
【56905】Re:別シートへ行と列を入れ替えてコピー 初心者さっち 08/7/10(木) 12:00 質問[未読]
【56906】Re:別シートへ行と列を入れ替えてコピー Abebobo 08/7/10(木) 12:36 発言[未読]
【56907】Re:別シートへ行と列を入れ替えてコピー 初心者さっち 08/7/10(木) 13:03 回答[未読]
【56908】Re:別シートへ行と列を入れ替えてコピー 初心者さっち 08/7/10(木) 13:15 回答[未読]
【56909】Re:別シートへ行と列を入れ替えてコピー kanabun 08/7/10(木) 13:47 発言[未読]
【56913】Re:別シートへ行と列を入れ替えてコピー 初心者さっち 08/7/10(木) 14:45 お礼[未読]

【56864】別シートへ行と列を入れ替えてコピー
質問  初心者さっち  - 08/7/9(水) 9:11 -

引用なし
パスワード
   おはようございます。

さっそく質問させていただきます。

sheets(1)にR11:Y11にランダムに数字が入ってます。nullはありません。
sheets(2)のC5:C12にコピーしたいのです。
R11=C5,S11=C6・・・というふうに。

Sub Cpy1()
  Worksheets(1).Range("R11:Y11").Copy _
  Destination:=Worksheets(2).Range("C5")
End Sub

上記マクロだとC5から横にコピーされてしまいます。
縦にコピーするにはどのように書けばいいでしょうか。

宜しくお願い致します。

【56866】Re:別シートへ行と列を入れ替えてコピー
回答  ハチ  - 08/7/9(水) 9:22 -

引用なし
パスワード
   ▼初心者さっち さん:

>上記マクロだとC5から横にコピーされてしまいます。
>縦にコピーするにはどのように書けばいいでしょうか。

Transposeを調べて見てください。

【56868】Re:別シートへ行と列を入れ替えてコピー
質問  初心者さっち  - 08/7/9(水) 11:27 -

引用なし
パスワード
   ハチ様 皆様

>Transposeを調べて見てください。
調べたのですが、どのように使うか理解できませんでした。
ううう。

違う方法で、転記する事はできました!!!
Sub Cpy1()
  Dim S1 As Worksheet, S2 As Worksheet
  Dim COL As Integer
  Dim GYO2 As Integer, COL2 As Integer
  
  Set S1 = Worksheets(1): Set S2 = Worksheets(2)
'転記先初期値
  GYO2 = 18
  COL2 = 5

'列ループ
  For COL = 5 To 12
'単一セルの転記
  S2.Cells(COL2, 3).Value = S1.Cells(11, GYO2).Value
'次の行列の判定
  COL2 = COL2 + 1
  If COL2 < 13 Then
    GYO2 = GYO2 + 1
  End If
 Next COL
End Sub

でも上記だと、応用がききません。
実は、これを元に連続で転記していきたいのです。

上の例では、sheets(2).cells(5,3)〜cells(12,3)
      sheets(1).cells(18,11)〜cells(25,11)
の転記しかできません。

転記したいsheets(1)のデータはまだまだ下へ11行〜1207行まで4行飛ばしであります。
【sheets(1)データ】
11行のデータのセル場所 【R11:Y11】,【AA11:AH11】,【AJ11:AQ11】
15行のデータのセル場所 【R15:Y15】,【AA15:AH15】,【AJ15:AQ15】
19行のデータのセル場所 【R19:Y19】,【AA19:AH19】,【AJ19:AQ19】
23行のデータのセル場所 【R23:Y23】,【AA23:AH23】,【AJ23:AQ23】
というような具合に4行飛ばしで、1207行まで続きます。

【sheets(2)転記位置】←曲者
sheets(1)の11行目のデータを左から順に【C5:C12】,【E5:E12】,【H5:H12】
sheets(1)の15行目のデータを左から順に【K5:K12】,【M5:M12】,【P5:P12】
sheets(1)の19行目のデータを左から順に【C21:C28】,【E21:E28】,【H21:H28】
sheets(1)の23行目のデータを左から順に【K21:K28】,【M21:M28】,【P21:P28】
という具合に転記していきたいのです。
イメージが沸きにくいかもしれませんが、左→右→左下→右下→左下→右下と続いて行きます。
列は、C,E,H,K,M,P
行は16行飛ばしで下へ、と法則があります。

煮詰まっています。
どうかお力添えの程宜しくお願いします。

【56869】Re:別シートへ行と列を入れ替えてコピー
発言  kanabun  - 08/7/9(水) 12:02 -

引用なし
パスワード
   ▼初心者さっち さん:

Transposeの参考にしてください

Sub TranspoCopy()
  Worksheets(1).Range("R11:Y11").Copy
  Worksheets(2).Range("C5").PasteSpecial Transpose:=True
End Sub

Sub TranspoValue()
  Dim y As Long, x As Long
  With Worksheets(1).Range("R11:Y11")
    y = .Rows.Count
    x = .Columns.Count
    Worksheets(2).Range("C5").Resize(x, y).Value = _
           Application.Transpose(.Cells)
  End With
End Sub

【56873】Re:別シートへ行と列を入れ替えてコピー
発言  ハチ  - 08/7/9(水) 13:19 -

引用なし
パスワード
   ▼初心者さっち さん:
>>Transposeを調べて見てください。
>調べたのですが、どのように使うか理解できませんでした。
>ううう。

Transposeは、kanabunさんのレスを参考にしてください。

左上のセルのアドレスを割り出してみました。
さっちさんの書き込みの内容をそのままコード化すると、こんな感じですか?
結果は、イミディエイトで見てください。

お昼を食べながら書いたので、バグがあるかも。

Sub Test1()
  Dim r As Long
  Dim c As Integer
  Dim i As Long
  Dim Col(1 To 6) As String
  Dim Sou_adr() As String 'コピー元のアドレス配列
  Dim Des_adr() As String 'コピー先のアドレス配列
  
  'コピー元のアドレス生成
  ReDim Sou_adr(0): i = 0
  For r = 11 To 1027 Step 4
    For c = 18 To 36 Step 9
      ReDim Preserve Sou_adr(i)
      Sou_adr(i) = Cells(r, c).Address(0, 0)
      i = i + 1
    Next
  Next
  
  'コピー先のアドレス生成
  ReDim Des_adr(0): i = 0
  Col(1) = "c": Col(2) = "E": Col(3) = "H"
  Col(4) = "K": Col(5) = "M": Col(6) = "P"
  For r = 5 To 2100 Step 16 '実際は To ・・いくつ?
    For c = 1 To 6
      ReDim Preserve Des_adr(i)
      Des_adr(i) = Range(Col(c) & r).Address(0, 0)
      i = i + 1
    Next
  Next
  Erase Col
  
  'Debug.Print UBound(Sou_adr)
  'Debug.Print UBound(Des_adr)
  
  For i = 0 To 99 'とりあえず、100パターン書き出し
    Debug.Print Sou_adr(i) & " → " & Des_adr(i)
  Next
  
  Erase Sou_adr
  Erase Des_adr
  
End Sub

【56874】Re:別シートへ行と列を入れ替えてコピー
発言  ハチ  - 08/7/9(水) 13:33 -

引用なし
パスワード
   >  'コピー先のアドレス生成

>      Des_adr(i) = Range(Col(c) & r).Address(0, 0)

Des_adr(i) = Col(c) & r

で、良いですね。失礼しました。

【56883】Re:別シートへ行と列を入れ替えてコピー
質問  初心者さっち  - 08/7/9(水) 16:48 -

引用なし
パスワード
   ▼ハチ様

>左上のセルのアドレスを割り出してみました。
>さっちさんの書き込みの内容をそのままコード化すると、こんな感じですか?
>結果は、イミディエイトで見てください。
>
>お昼を食べながら書いたので、バグがあるかも。
>
>Sub Test1()
>  Dim r As Long
>  Dim c As Integer
>  Dim i As Long
>  Dim Col(1 To 6) As String
>  Dim Sou_adr() As String 'コピー元のアドレス配列
>  Dim Des_adr() As String 'コピー先のアドレス配列
>  
>  'コピー元のアドレス生成
>  ReDim Sou_adr(0): i = 0
  'Sou_adrに1つ配列を割り当てる? 0だけを割り当てる?
  
>  For r = 11 To 1027 Step 4
>    For c = 18 To 36 Step 9
     'なぜ9飛ばしの36までなのですか?

>      ReDim Preserve Sou_adr(i)
       '配列の最後の要素数をiにする?

>      Sou_adr(i) = Cells(r, c).Address(0, 0)
       'Address(0,0)ってどういうことですか?
>      i = i + 1
>    Next
>  Next
>  
>  'コピー先のアドレス生成
>  ReDim Des_adr(0): i = 0
>  Col(1) = "c": Col(2) = "E": Col(3) = "H"
>  Col(4) = "K": Col(5) = "M": Col(6) = "P"
>  For r = 5 To 2100 Step 16 '実際は To ・・いくつ?
   'toは、上の1207のデータが転記されるまでなのですが。
   わからないです。
>    For c = 1 To 6
>      ReDim Preserve Des_adr(i)
>      Des_adr(i) = Range(Col(c) & r).Address(0, 0)
>      i = i + 1
>    Next
>  Next
>  Erase Col
>  
>  'Debug.Print UBound(Sou_adr)
>  'Debug.Print UBound(Des_adr)
>  
>  For i = 0 To 99 'とりあえず、100パターン書き出し
>    Debug.Print Sou_adr(i) & " → " & Des_adr(i)
>  Next
>  
>  Erase Sou_adr
>  Erase Des_adr
>  
>End Sub


すいません。難しいっす。
夕食を食べながらでもいいので、サルでも解るような解説をお願いします。

【56885】Re:別シートへ行と列を入れ替えてコピー
お礼  初心者さっち  - 08/7/9(水) 16:51 -

引用なし
パスワード
   ▼kanabun様

大変参考になります!!
まだ理解しておりませんが、がんばります。

:=がでてくるとびびります。

【56886】Re:別シートへ行と列を入れ替えてコピー
発言  kanabun  - 08/7/9(水) 17:18 -

引用なし
パスワード
   ▼初心者さっち さん:
こんにちは。

ここだけ ↓
>>      Sou_adr(i) = Cells(r, c).Address(0, 0)
>       'Address(0,0)ってどういうことですか?

ヘルプで調べましょう。
Range.Address(RowAbsolute, ColumnAbsolute, ReferenceStyle, External, RelativeTo)
とあります。

Address(0,0) ということはこの5つのパラメータのうち、前の2つが指定され
ているということで、それらが 0 ということは False が指定されていると
いうことです。
Address(False, False) ということです。

なぜなら、0 は False で、1 とか -1 とか とにかく 0でない
数値は True ですから。

MsgBox Range("A1").Address(1,1)
MsgBox Range("A1").Address(0,0)

として 絶対参照によるアドレス表現($付き) と相対参照による表現のちがいを
確かめてください。

【56887】Re:別シートへ行と列を入れ替えてコピー
発言  ハチ  - 08/7/9(水) 17:39 -

引用なし
パスワード
   ▼初心者さっち さん:

>>結果は、イミディエイトで見てください。

この結果は、どうでしたか?
想定通りのアドレスが表示されましたか?

>>  Dim Sou_adr() As String 'コピー元のアドレス配列

>>  'コピー元のアドレス生成
>>  ReDim Sou_adr(0): i = 0
>  'Sou_adrに1つ配列を割り当てる? 0だけを割り当てる?

Sou_adrは『動的配列』で宣言しています。
ReDim Sou_adr(0) で、中身はカラッポと明示しています。
今回のコードでいけば、無くても動きます。
 
>>  For r = 11 To 1027 Step 4
>>    For c = 18 To 36 Step 9
>     'なぜ9飛ばしの36までなのですか?

コピー元のカラムは、
R=18列, AA=27列, AJ=36列 と9飛ばしの法則性がありました。

>>      ReDim Preserve Sou_adr(i)
>       '配列の最後の要素数をiにする?

ちょっと違います。別レスにサンプルを書いてみます。

>>      Sou_adr(i) = Cells(r, c).Address(0, 0)
>       'Address(0,0)ってどういうことですか?

これは、ヘルプを見てください。

>>  'コピー先のアドレス生成
>>  ReDim Des_adr(0): i = 0
>>  Col(1) = "c": Col(2) = "E": Col(3) = "H"
>>  Col(4) = "K": Col(5) = "M": Col(6) = "P"
>>  For r = 5 To 2100 Step 16 '実際は To ・・いくつ?
>   'toは、上の1207のデータが転記されるまでなのですが。
>   わからないです。

rは、rowの意図で書きました。
転記先のrowは、何行目まで使うのか? ということです。

>すいません。難しいっす。
>夕食を食べながらでもいいので、サルでも解るような解説をお願いします。

そうですね・・・ちょっとややこしかったですね。
もっと良い案が出るかもしれませんので、厳しかったらスルーしてください。

【考え方】
法則性の違う2つアドレスを同時に生成しながら、
ループを回そうとすると頭が混乱します。

まずは、配列(今回は、Sou_adr と Des_adr)に、
1対1の関係になるようにアドレスを整列します。

1対1の関係の関係になれば、
後は必要な回数ループを回してコピーして行けば良いと考えました。
Sou_adr(0) から Des_adr(0) へコピー
Sou_adr(1) から Des_adr(1) へコピー



【56888】Re:別シートへ行と列を入れ替えてコピー
発言  ハチ  - 08/7/9(水) 17:54 -

引用なし
パスワード
   >
>>>      ReDim Preserve Sou_adr(i)
>>       '配列の最後の要素数をiにする?
>
>ちょっと違います。別レスにサンプルを書いてみます。
>

ここの部分のサンプルを書いてみます。
わかりやすいか?というと、ビミョーな気がしますが・・・

Sub Sample()
  Dim i As Integer
  Dim cnt As Integer 'カウンターの意
  Dim buf() As Variant
  
  '初期化
  ReDim buf(0): cnt = 0
  
  '0〜10までを動的配列bufを拡張しながら、入れる
  For i = 0 To 10
    '現在の配列を初期化せずに、要素数を変更する
    ReDim Preserve buf(cnt)
    'buf(index値)に値を入れる
    buf(cnt) = i
    '使ったので、+1する
    cnt = cnt + 1
  Next
  '配列bufの中身を見てみる
  For i = LBound(buf) To UBound(buf)
    MsgBox buf(i)
  Next
  '全部ならべて、見てみる
  MsgBox Join(buf, ",")
  
  '要らなくなったら、開放する
  Erase buf
  
End Sub

【56897】Re:別シートへ行と列を入れ替えてコピー
お礼  初心者さっち  - 08/7/10(木) 9:07 -

引用なし
パスワード
   ▼ハチ様
ご返信遅くなりました。

今から、習熟致します。
また、ご返信いたします!!

結構かかりそうなので、また気が向いたら、のぞいてください。

ありがとうございます。

【56899】Re:別シートへ行と列を入れ替えてコピー
お礼  初心者さっち  - 08/7/10(木) 10:27 -

引用なし
パスワード
   ▼ハチ様
お早うございます!!

朝は頭が冴えますね。

ReDim Preserve Sou_adr(i)
理解できました!!

が、Preserveを書かずにReDim Sou_adr(i)と記述すると、
10のみが表示されます。これは、iが初期されていき、最終的に
10がindex値になるからでしょうか。

あってます?w

続けて、メインのほうも習熟いたします。
スルーはしないです。がんばります!

【56900】Re:別シートへ行と列を入れ替えてコピー
発言  kanabun  - 08/7/10(木) 10:39 -

引用なし
パスワード
   こんにちは。

▼Copy元範囲のアドレス
> 【sheets(1)データ】
> 11行のデータのセル場所 【R11:Y11】,【AA11:AH11】,【AJ11:AQ11】
> 15行のデータのセル場所 【R15:Y15】,【AA15:AH15】,【AJ15:AQ15】
> 19行のデータのセル場所 【R19:Y19】,【AA19:AH19】,【AJ19:AQ19】
> 23行のデータのセル場所 【R23:Y23】,【AA23:AH23】,【AJ23:AQ23】

上の4行は、こういう風にも考えられませんか?

[R11]を基点として【A1:H1】,【J1:Q1】,【S1:Z1】
         【A5:H5】,【J5:Q5】,【S5:Z5】、

[R19]を基点として【A1:H1】,【J1:Q1】,【S1:Z1】
         【A5:H5】,【J5:Q5】,【S5:Z5】、

つまり、2行を1ブロックと考えると、起点セルの座標が単調増加するだけで、
Copy範囲の相対位置はどのブロックでも同じ、ということ。

'コピー先についても同じ。


Sub Try1()
 Dim r As Range
 Dim c As Range
 
 Set r = Worksheets(1).[R11] '最初のCopyブロック基点セル
 Set c = Worksheets(2).[C5] '最初のPaste先セル
 
 Do
   BlockCopy r, c
   
   Set r = r.Offset(8) 'つぎのブロック先頭へ
   Set c = c.Offset(16)
 Loop Until r.Row > 1207
 
End Sub

Private Sub BlockCopy(ByVal r As Range, ByVal c As Range)
 With r
  .Range("A1:H1").Copy
     c.Range("A1").PasteSpecial xlValues, Transpose:=True
  .Range("J1:Q1").Copy
     c.Range("C1").PasteSpecial xlValues, Transpose:=True
  .Range("S1:Z1").Copy
     c.Range("F1").PasteSpecial xlValues, Transpose:=True
  
  .Range("A5:H5").Copy
     c.Range("I1").PasteSpecial xlValues, Transpose:=True
  .Range("J5:Q5").Copy
     c.Range("K1").PasteSpecial xlValues, Transpose:=True
  .Range("S5:Z5").Copy
     c.Range("N1").PasteSpecial xlValues, Transpose:=True
 End With
End Sub

【56901】Re:別シートへ行と列を入れ替えてコピー
お礼  初心者さっち  - 08/7/10(木) 10:56 -

引用なし
パスワード
   ▼kanabun さん:
>こんにちは。
>
>▼Copy元範囲のアドレス
>> 【sheets(1)データ】
>> 11行のデータのセル場所 【R11:Y11】,【AA11:AH11】,【AJ11:AQ11】
>> 15行のデータのセル場所 【R15:Y15】,【AA15:AH15】,【AJ15:AQ15】
>> 19行のデータのセル場所 【R19:Y19】,【AA19:AH19】,【AJ19:AQ19】
>> 23行のデータのセル場所 【R23:Y23】,【AA23:AH23】,【AJ23:AQ23】
>:
>上の4行は、こういう風にも考えられませんか?
>
>[R11]を基点として【A1:H1】,【J1:Q1】,【S1:Z1】
>         【A5:H5】,【J5:Q5】,【S5:Z5】、
>
>[R19]を基点として【A1:H1】,【J1:Q1】,【S1:Z1】
>         【A5:H5】,【J5:Q5】,【S5:Z5】、
>
>つまり、2行を1ブロックと考えると、起点セルの座標が単調増加するだけで、
>Copy範囲の相対位置はどのブロックでも同じ、ということ。
>
>'コピー先についても同じ。
>
>
>Sub Try1()
> Dim r As Range
> Dim c As Range
> 
> Set r = Worksheets(1).[R11] '最初のCopyブロック基点セル
> Set c = Worksheets(2).[C5] '最初のPaste先セル
> 
> Do
>   BlockCopy r, c
>   
>   Set r = r.Offset(8) 'つぎのブロック先頭へ
>   Set c = c.Offset(16)
> Loop Until r.Row > 1207
> 
>End Sub
>
>Private Sub BlockCopy(ByVal r As Range, ByVal c As Range)
> With r
>  .Range("A1:H1").Copy
>     c.Range("A1").PasteSpecial xlValues, Transpose:=True
>  .Range("J1:Q1").Copy
>     c.Range("C1").PasteSpecial xlValues, Transpose:=True
>  .Range("S1:Z1").Copy
>     c.Range("F1").PasteSpecial xlValues, Transpose:=True
>  
>  .Range("A5:H5").Copy
>     c.Range("I1").PasteSpecial xlValues, Transpose:=True
>  .Range("J5:Q5").Copy
>     c.Range("K1").PasteSpecial xlValues, Transpose:=True
>  .Range("S5:Z5").Copy
>     c.Range("N1").PasteSpecial xlValues, Transpose:=True
> End With
>End Sub

欲しい結果になりましたーーーーーーーー。

習熟します!!!!!!

調べてわからなかったら、また質問させてください!!!!

ありがとうざいます。!!

【56902】Re:別シートへ行と列を入れ替えてコピー
発言  ハチ  - 08/7/10(木) 11:10 -

引用なし
パスワード
   ▼初心者さっち さん:

>ReDim Preserve Sou_adr(i)
>理解できました!!
>
>が、Preserveを書かずにReDim Sou_adr(i)と記述すると、
>10のみが表示されます。これは、iが初期されていき、最終的に
>10がindex値になるからでしょうか。

初期化されるのは、i ではなく、Sou_adr配列のほうですね。
10は、index値の最大値です。UBound関数で取得できます。
もう1回サンプルを書いてみます。

本題の質問はkanabunさんのコードのほうが、遥かにわかり易いですので、
そちらを参考にしてください。

Sub Sample2()
  Dim i As Integer
  Dim cnt As Integer 'カウンターの意
  Dim buf() As Variant
  Dim v As Variant
   
  '初期化
  ReDim buf(0): cnt = 0
  v = Array("A", "B", "C", "D", "E")

  For i = 0 To UBound(v)
    '現在の配列を初期化せずに、要素数を変更する
    ReDim Preserve buf(cnt)
    
    buf(cnt) = v(i)
    '使ったので、カウンターを+1する
    cnt = cnt + 1
    '中身を表示
    MsgBox Join(buf, " , ") & vbCr & _
    "配列の要素 " & LBound(buf) & " 〜 " & UBound(buf)
  Next
  
  'index 1 の中身を表示
  MsgBox "buf(1)= " & buf(1)
  
  MsgBox "Preserveが無いと、配列の中身が初期化される"
  ReDim buf(UBound(buf))
  
  MsgBox Join(buf, " , ") & vbCr & _
  "配列の要素 " & LBound(buf) & " 〜 " & UBound(buf)

  'index 1 の中身を表示
  MsgBox "buf(1)= " & buf(1)

  '要らなくなったら、開放する
  Erase v
  Erase buf
 
End Sub

【56904】Re:別シートへ行と列を入れ替えてコピー
発言  kanabun  - 08/7/10(木) 11:22 -

引用なし
パスワード
   ▼初心者さっち さん:
>欲しい結果になりましたーーーーーーーー。

最終行はよかったですか? ちょっと自信がありません。

あと、
いま、Transpose Value のほうでテストしてみたら、全然スピードが
ちがうので、報告します。値の転記だけなら、こちらのほうがいいみたい

Sub Try2()
 Dim r As Range
 Dim c As Range

 Set r = Worksheets(1).[R11] '最初のCopyブロック基点セル
 Set c = Worksheets(2).[C5] '最初のPaste先セル
 
 Application.ScreenUpdating = False
 Do
   TranspoValue r, c
   
   Set r = r.Offset(8) 'つぎのブロック先頭へ
   Set c = c.Offset(16)
 Loop Until r.Row > 1207
 
 Application.ScreenUpdating = True
 Beep
End Sub

Private Sub TranspoValue(ByVal r As Range, ByVal c As Range)
 With Application
  c.Range("A1").Resize(8).Value = .Transpose(r.Range("A1:H1"))
  c.Range("C1").Resize(8).Value = .Transpose(r.Range("J1:Q1"))
  c.Range("F1").Resize(8).Value = .Transpose(r.Range("S1:Z1"))
  
  c.Range("I1").Resize(8).Value = .Transpose(r.Range("A5:H5"))
  c.Range("K1").Resize(8).Value = .Transpose(r.Range("J5:Q5"))
  c.Range("N1").Resize(8).Value = .Transpose(r.Range("S5:Z5"))
 End With
End Sub

ちなみに、こちらの環境では
ともに、
 Application.ScreenUpdating = False/True
を入れて、

 ◆Try1 CopyPaste が 4.129 秒
 ◆Try2 TransValue が 0.367 秒 でした。

【56905】Re:別シートへ行と列を入れ替えてコピー
質問  初心者さっち  - 08/7/10(木) 12:00 -

引用なし
パスワード
   ▼kanabun様
>上の4行は、こういう風にも考えられませんか?
考えられます!!

>[R11]を基点として【A1:H1】,【J1:Q1】,【S1:Z1】
>         【A5:H5】,【J5:Q5】,【S5:Z5】、
>
>[R19]を基点として【A1:H1】,【J1:Q1】,【S1:Z1】
>         【A5:H5】,【J5:Q5】,【S5:Z5】、
>
>Sub Try1()
> Dim r As Range
> Dim c As Range
> 
> Set r = Worksheets(1).[R11] '最初のCopyブロック基点セル
> Set c = Worksheets(2).[C5] '最初のPaste先セル
 'なぜ[]←を使用するのですか?基点にするセルを指定する時は、[]を使用するの  ですか?()ではだめなのですか?
 '基点の考えかたはすごく勉強になります。応用がききそうですね。
 
> Do
>   BlockCopy r, c
>   
>   Set r = r.Offset(8) 'つぎのブロック先頭へ
   'ヘルプを見てもいまいちイメージできなかったのですが、
   列と行の指定ができるとおもうのですが、省略している場合は、
   横方向へ8ってことになるのですか?

>   Set c = c.Offset(16)
    'れは下方向に16?上と記述がかわらないのに、下へいくのですか?
     いません。教えてください。

> Loop Until r.Row > 1207
  r行が、1207行になるまで、BlockCopyしなさいってことですか。
>End Sub
>
>Private Sub BlockCopy(ByVal r As Range, ByVal c As Range)
'ByValって、sub Try()のr,cをこっちでも使うってことですか。
> With r
>  .Range("A1:H1").Copy
>     c.Range("A1").PasteSpecial xlValues, Transpose:=True
   '基点にしたセルrから、("A1:H1")分をコピー
     '基点にしたセルCから、"A1"分の所に貼付ける
      Transposeがtrueなら。Transposeが解りません。ヘルプがでてきませ      んでした。ううう。

>  .Range("J1:Q1").Copy
>     c.Range("C1").PasteSpecial xlValues, Transpose:=True
>  .Range("S1:Z1").Copy
>     c.Range("F1").PasteSpecial xlValues, Transpose:=True
>  
>  .Range("A5:H5").Copy
>     c.Range("I1").PasteSpecial xlValues, Transpose:=True
>  .Range("J5:Q5").Copy
>     c.Range("K1").PasteSpecial xlValues, Transpose:=True
>  .Range("S5:Z5").Copy
>     c.Range("N1").PasteSpecial xlValues, Transpose:=True
> End With
>End Sub


上記に対しご教示の程宜しくお願い致します。

【56906】Re:別シートへ行と列を入れ替えてコピー
発言  Abebobo  - 08/7/10(木) 12:36 -

引用なし
パスワード
   初心者さっち さん こんいちは
kanabunさんではありませんが、私も同じところで うぅ〜ん と思った事があったので…。

> Set r = Worksheets(1).[R11]
 は Set r = Worksheets(1).Range("R11") と同じと考えてよいのでしょうか。
打ち込むのに簡単ですよね。こちらの書き方をする方もいます。

ついでに 
>>   Set r = r.Offset(8) 'つぎのブロック先頭へ

Offset(行数,列数) なので、Offset(8,0) って事です。
列の時には、Offset(,8) って事です ←半角で書くと , と括弧が重なって見づらいので全角で書きました。

【56907】Re:別シートへ行と列を入れ替えてコピー
回答  初心者さっち  - 08/7/10(木) 13:03 -

引用なし
パスワード
   ▼Abebobo さん:
>ついでに 
>>>   Set r = r.Offset(8) 'つぎのブロック先頭へ
>
>Offset(行数,列数) なので、Offset(8,0) って事です。
>列の時には、Offset(,8) って事です ←半角で書くと , と括弧が重なって見づらいので全角で書きました。

'すいません。自己解決致しました。たぶん。
上記のOffsetは基点セルからの範囲を決める為だけのもので、
rはそのまま、行方向に作用させ。
cはTranspose:=trueでペーストさせてるんですよね。

あってますでしょうか?w
kanabun様、abebobo様

【56908】Re:別シートへ行と列を入れ替えてコピー
回答  初心者さっち  - 08/7/10(木) 13:15 -

引用なし
パスワード
   ▼初心者さっち さん:
>▼Abebobo さん:
>>ついでに 
>>>>   Set r = r.Offset(8) 'つぎのブロック先頭へ
>>
>>Offset(行数,列数) なので、Offset(8,0) って事です。
>>列の時には、Offset(,8) って事です ←半角で書くと , と括弧が重なって見づらいので全角で書きました。
>
>'すいません。自己解決致しました。たぶん。
>上記のOffsetは基点セルからの範囲を決める為だけのもので、
>rはそのまま、行方向に作用させ。
>cはTranspose:=trueでペーストさせてるんですよね。
>
>あってますでしょうか?w
>kanabun様、abebobo様

すいません。
たぶん間違ってますねw

普通にrも下方向に8行いってましたw
rの範囲を行と列を入れ替えてコピーしてるんですよね。
Transpose:=trueわ。

もっと精進致します。

【56909】Re:別シートへ行と列を入れ替えてコピー
発言  kanabun  - 08/7/10(木) 13:47 -

引用なし
パスワード
   ▼初心者さっち さん:
>▼kanabun様
>>上の4行は、こういう風にも考えられませんか?
>考えられます!!
>
>>[R11]を基点として【A1:H1】,【J1:Q1】,【S1:Z1】
>>         【A5:H5】,【J5:Q5】,【S5:Z5】、
>>
>>[R19]を基点として【A1:H1】,【J1:Q1】,【S1:Z1】
>>         【A5:H5】,【J5:Q5】,【S5:Z5】、
>>
>>Sub Try1()
>> Dim r As Range
>> Dim c As Range
>> 
>> Set r = Worksheets(1).[R11] '最初のCopyブロック基点セル
>> Set c = Worksheets(2).[C5] '最初のPaste先セル
> 'なぜ[]←を使用するのですか?基点にするセルを指定する時は、[]を使用するの  ですか?()ではだめなのですか?
Worksheets(1).[R11] は
 Worksheets(1).Range("R11") の簡略表現です。
 .[R11] を使うと、処理スピードは .Range("R11") と書くより遅くなりますが、
 範囲が分かりやすいので、処理手順を考えるときはよくこれを使います。
 実用化するときは、.Range("R11") に直しておいてくださいね。(^^

> '基点の考えかたはすごく勉強になります。応用がききそうですね。
> 
>> Do
>>   BlockCopy r, c
>>   
>>   Set r = r.Offset(8) 'つぎのブロック先頭へ
>   'ヘルプを見てもいまいちイメージできなかったのですが、
>   列と行の指定ができるとおもうのですが、省略している場合は、
>   横方向へ8ってことになるのですか?
Range.Offset(RowOffset, ColumnOffset)
ですから、
   Set r = r.Offset(8)
は、
   Set r = r.Offset(8,0)  のことで、
   現在の r から「行方向に+8」オフセットする、ということです。
もし、
  c.Offset(,4)
とあったら、 ★カンマの前が省略されている 訳だから、
現在のc から 「列方向」に +4列右 ということになります。


>> Loop Until r.Row > 1207
>  r行が、1207行になるまで、BlockCopyしなさいってことですか。
  正確には 1207行を超えるまで、ですね?

>>Private Sub BlockCopy(ByVal r As Range, ByVal c As Range)
>'ByValって、sub Try()のr,cをこっちでも使うってことですか。
ここは、ちがいます。
「r」とか 「c」とかは「引数(パラメータ)」と呼ばれるもので、読みやすく
するために、たまたま 呼び出し側で使っている変数名と同じにしましたが、
別に名前は何でもかまいません。
パラメータの前に修飾してある ByVal というのは
(ちょっと難しくなりますが)呼び出し側から情報をどのように渡すかを
指定しているものです。「どのように」に2つあり、
ひとつが ByVal で もうひとつが ByRef です。
Helpの Subプロシージャの解説を読むと
 ByVal その引数が、値渡しで渡されることを示します。
 ByRef その引数が、参照渡しで渡されることを示します。Visual Basic では、既定値は ByRef です。
とあります。これだけではよく分からないのですが、
たとえば、呼び出し側から渡される引数を E-メールに例えると、
 ・ByValのほうは メールのコピーが渡される、
 ・ByRefのほうは サーバーに置いてあるメールの在りかが渡される、
  (あるいは、郵便物として呼び出し側で書いたメール本文が届けられる)
というようなちがいです。
どういうことかというと、ByVal渡しされたものはメールのコピーですから、
あなたが受け取ったメールの内容を改竄(ざん)しても、送信元のオリジナル
メール内容はなんら変更されません。
いっぽう、byRefで送ると、受け取り側がメールの置いてあるサーバーに
アクセスして内容を削除してしまったり、送られた手紙のうえにコーヒー
をこぼしてしまったりすると、そのメールや手紙に対する変更は、送り手
のオリジナルの変更にもなります。
こういう違いがあります。まぁ、Rangeなどのオブジェクトを渡すときは
深く考えないで、いつも byVal スタイルで渡すことになっている、とだけ
記憶しておいてください。

>> With r
>>  .Range("A1:H1").Copy
>>     c.Range("A1").PasteSpecial xlValues, Transpose:=True
>   '基点にしたセルrから、("A1:H1")分をコピー
>     '基点にしたセルCから、"A1"分の所に貼付ける
>      Transposeがtrueなら。Transposeが解りません。ヘルプがでてきませ
>      んでした。ううう。
一般機能で、 r.[A1:H1] をCopyして、
別シートのc セルを指定して、「形式を選択して貼り付け」メニュ-から
・値のみ
・行列を入れ替える
にチェックを入れて貼り付ける操作をマクロ記録してみてください。
>--------------------------------------------------------------
Sheet1 の

A1 B1 C1
A2 B2 C2
A3【B3 C3】

Sheet1.[B3:C3] は 
 Sheet1.[A3]を基点として表現するなら
 Sheet1.Range("A3").Range("B1:C1") ということですし、
 Sheet1.Cells(3,1).Range("B1:C1") でもおなじ。
 Sheet1.Range("A3").Offset(,1).Resize(,2) とも表現できます。
ちなみに、
Sheet1の【B3 C3】セルを基点とすれば、そのOffset(-2)は
Sheet1の [B1:C1]セル範囲のことですし、
【B3 C3】セルから .Offset(-2,-1).Resize(1,1) したセルは[A1]セルの
ことです。
Sheet1の[A1]セルは Sheet1.Cells(1,1) または Sheet1.Cells(1)
すなわち、 Sheet1.Range("A1").Item(1,1) のことですが、
Sheet1.Range("B3").Item(1,2) といったら、 sheet1.[C3] のこと、
Sheet1.Range("B3").Item(-1,0) といったら、 sheet1.[A1] のこと
になります♪

【56913】Re:別シートへ行と列を入れ替えてコピー
お礼  初心者さっち  - 08/7/10(木) 14:45 -

引用なし
パスワード
   ▼kanabun様
すごくわかりやすいです!!
ありがとうございます。

でもまだ理解しきれていません。w
がんばります!!

【56918】Re:別シートへ行と列を入れ替えてコピー
質問  初心者さっち  - 08/7/10(木) 16:10 -

引用なし
パスワード
   ▼kanabun様
お疲れ様です。

> ◆Try1 CopyPaste が 4.129 秒
> ◆Try2 TransValue が 0.367 秒 でした。
Try1のCopyPasteの方は、理解ができました!ありがとうございます。

Try2の方は、今から取り掛かろうとおもっているのですが、
■-1,Application.ScreenUpdating = False/True
■-2,With Application

上記二つが、Try1に比べ大きく変わっているかと思います。
■-1は、更新をせず、一発で転記させるというのはわかるのですが、
■-2は、よく理解できないのです。
オブジェクトを返すプロパティ・・。

ヒントをお願いします。

【56919】Re:別シートへ行と列を入れ替えてコピー
発言  kanabun  - 08/7/10(木) 17:04 -

引用なし
パスワード
   > お疲れ様です。
>
> > ◆Try1 CopyPaste が 4.129 秒
> > ◆Try2 TransValue が 0.367 秒 でした。
> Try1のCopyPasteの方は、理解ができました!ありがとうございます。
>
> Try2の方は、今から取り掛かろうとおもっているのですが、
>
> 上記二つが、Try1に比べ大きく変わっているかと思います。
> ■-1,Application.ScreenUpdating = False/True
>  は、更新をせず、一発で転記させるというのはわかるのですが、
 Application.ScreenUpdating = False
は、画面の更新を抑止するものです。なので、
Try1() にも、 Try2()にも必要です。
シートに盛んにアクセスしてますから。

> > ◆Try1 CopyPaste が 4.129 秒
 これは
 Application.ScreenUpdating = False
 を入れたあとの計測データです。


> ■-2,With Application
>  は、よく理解できないのです。
> オブジェクトを返すプロパティ・・。
 これまで Withステートメントを使われたことなかったですか?

>  With Application
>   c.Range("A1").Resize(8).Value = .Transpose(r.Range("A1:H1"))
>   c.Range("C1").Resize(8).Value = .Transpose(r.Range("J1:Q1"))
>   c.Range("F1").Resize(8).Value = .Transpose(r.Range("S1:Z1"))
>   
>   c.Range("I1").Resize(8).Value = .Transpose(r.Range("A5:H5"))
>   c.Range("K1").Resize(8).Value = .Transpose(r.Range("J5:Q5"))
>   c.Range("N1").Resize(8).Value = .Transpose(r.Range("S5:Z5"))
>  End With

ここは、With 使わないと、こうなります。
c.Range("A1").Resize(8).Value = Application.Transpose(r.Range("A1:H1"))
c.Range("C1").Resize(8).Value = Application.Transpose(r.Range("J1:Q1"))
c.Range("F1").Resize(8).Value = Application.Transpose(r.Range("S1:Z1"))

c.Range("I1").Resize(8).Value = Application.Transpose(r.Range("A5:H5"))
c.Range("K1").Resize(8).Value = Application.Transpose(r.Range("J5:Q5"))
c.Range("N1").Resize(8).Value = Application.Transpose(r.Range("S5:Z5"))

このように、.Transposeのまえに 毎行 Applicationを書かないといけません。
もちろんそれでよいのですが、あ〜メンドイと思ったら、迷わず、
最初に一回だけ
 With Application
と宣言しておけば、「.Transpose 」とピリオドから打ち込むだけで
ピリオドの前に Applicationオブジェクトがあるかのように動作します。
(Withステートメントを使ったほうが若干動作も速いです)

なお、With に対応する
   End With をお忘れなく。

4401 / 13646 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free