2016-03-29 10 views
0

まず、読んでいただきありがとうございました。Excelで1つのシートから別のシートに複数の行をコピーするコード

私は基本的にここでは無知です。私は最後の数日間、私がやりたいことをコード化する方法を理解しようとしました。私はそれをはっきりと説明しようとします。

私のワークブックには複数のシートがありますが、そのうちの2枚だけがこれに関係します:スケジュール&シフト。

スケジュールでは、1つの列に従業員名(列A)、頭字語(B)、従業員番号(C)、シフト(D)およびシフト時間を含む17列と40〜100行E - vlookupを介して別のシートに返されます)。

基本的には、これらの5つの列のそれぞれのデータを「A3」から始まるShiftシートにコピーし、名前の空白フィールドに達するまでScheduleの行をコピーし続けます列A)。

これまでのところ、私は次のコードで1行目と2行目をコピーするために管理してきました:

Private Sub CommandButton1_Click() 
Dim i As Integer, IntName As String, IntInit As String, IntID As Integer, Shift As String, Hours As Integer 
    Worksheets("Schedule").Select 
    i = 1 
    IntName = Range("a4") 
    IntInit = Range("b4") 
    IntID = Range("C4") 
    Shift = Range("D4") 
    Hours = Range("E4") 

    Do While i < 5 

    Worksheets("Shift").Select 
    Worksheets("Shift").Range("a2").Select 

    If Worksheets("Shift").Range("a2").Offset(1, 0) <> "" Then 
    Worksheets("Shift").Range("a2").End(xlDown).Select 
    End If 

    ActiveCell.Offset(1, 0).Select 
    ActiveCell.Value = IntName 
    ActiveCell.Offset(0, 1).Select 
    ActiveCell.Value = IntInit 
    ActiveCell.Offset(0, 1).Select 
    ActiveCell.Value = IntID 
    ActiveCell.Offset(0, 1).Select 
    ActiveCell.Value = Shift 
    ActiveCell.Offset(0, 1).Select 
    ActiveCell.Value = Hours 
    Worksheets("Schedule").Select 

    IntName = Worksheets("Schedule").Range("a4").Offset(1, 0) 
    IntInit = Worksheets("Schedule").Range("b4").Offset(1, 0) 
    IntID = Worksheets("Schedule").Range("c4").Offset(1, 0) 
    Shift = Worksheets("Schedule").Range("d4").Offset(1, 0) 
    Hours = Worksheets("Schedule").Range("e4").Offset(1, 0) 

    i = i + 1 

    Loop 



End Sub 

明らかに、これは不格好であり、それは実際に私は超えてやりたいしません。 2回目はループを通ります。

私が正しい方向に動くのを助けるための提案や指針はありますか?

もう一度おねがいします。

+1

簡単なメモ、I **非常に** [ '.Select'を使用して回避する方法]を一読をお勧めします(http: //stackoverflow.com/questions/10714251/how-to-avoid-using-select-in-excel-vba-macros)。それは多くの頭痛を救うことができ、本当にあなたの理解をループで助けることができます。 – BruceWayne

答えて

0

あなたは正しい経路にいるので、ループを別のループにネストする必要があります。また、@ BruceWayneの助言に耳を傾ける。

Private Sub CommandButton1_Click() 
    Dim i As Integer 
    Dim intCounter As Integer 
    Dim IntName As String 
    Dim IntInit As String 
    Dim IntID As Integer 
    Dim Shift As String 
    Dim Hours As Integer 

    'Adjust intCounter if you want to start on a row other than 1 
    intCounter = 1 

    Do 
     With Worksheets("Schedule") 
      IntName = .Cells(intCounter, 1).Value 
      IntInit = .Cells(intCounter, 2).Value 
      IntID = .Cells(intCounter, 3).Value 
      Shift = .Cells(intCounter, 4).Value 
      Hours = .Cells(intCounter, 5).Value 
     End With 

     If IntName = "" Then Exit Do 

     i = 1 
     Do While i < 5 
      'No need to use offset when you can just reference the cell directly. 
      'Also, not sure why you select this column anyhow. 
      'These lines can probably be deleted? 
      'If Worksheets("Shift").Range("a3").Value <> "" Then 
      ' Worksheets("Shift").Range("a2").End(xlDown).Select 
      'End If 

      'Avoid using things like Select, ActiveCell, and ActiveSheet. 
      'What if someone clicks on something while your code is running?? Oops! 
      With Worksheets("Shift") 
       .Cells(i + 1, 2).Value = IntName 
       .Cells(i + 1, 3).Value = IntInit 
       .Cells(i + 1, 4).Value = IntID 
       .Cells(i + 1, 5).Value = Shift 
       .Cells(i + 1, 6).Value = Hours 
      End With 

      i = i + 1 
     Loop 

     'Increment to go to the next row of Schedule 
     intCounter = intCounter + 1 
    Loop 
End Sub 
+0

注意:外側のループには終了条件はありません! – user3598756

+0

ああ? 'If​​ IntName =" "Then Exit Do' – Tim

+1

あなたは正しいです。 "Do"と "Loop"ステートメントだけを見たので、私はそれを逃した。とにかく、私はいつもそれらの2つのステートメントのうちの1つに最終状態を保つ良い習慣としてそれをとるだろう。 – user3598756

0
コンパクトなコードについてティムの懸念によってもたらさ

、してみてください。この

Private Sub CommandButton1_Click() 

With Worksheets("Schedule").Range("A4:E4").CurrentRegion 
    .Offset(1).Resize(.Rows.Count - 1).Copy Destination:=Worksheets("Shift").Range("A3") 
End With 

End Sub