2012-03-08 15 views
3

私はあるシートから別のシートにデータをコピーするはずのvbaスクリプトを持っています。 3つのネストされたforループを使用して行います。これらをデバッグする際にコードを実行すると完全に動作するように見えますが、vbaスクリプトを実行すると早すぎると思われます。それ以外の場合は、vbaスクリプトが動作します。VBAネストされたループが早期に終了する

私はこれを何時間も見つめていて、私の人生にとってループが早期に止まる原因を知ることはできません。私は解決策が私が逃したシンプルなものだと思っていますが、私はこれを始めてから初めてではなく、本物の喪失に瀕しています。

次のようにシートが構成されています

シート1は、コピーするデータを含みます。

  • 各行は55
  • テストデータ内のシートがあり、そのうちの別々の応答が含まエピソード1-9名前付きデータの9つのブロックを含んでいます。各エピソードには、整数が開始時刻、終了時刻、および間隔時間を表す列が含まれます。
  • テストデータでは、各エピソードは開始/終了時刻を除いて同一です。
  • 終了時間の最大値は36
  • あるEpisode4が終了時間データ を移動する=行ごとに36

シート2を含有するように、テストデータは、唯一の最初の4つのエピソードブロック上にあります - 最初の列には36行にわたってコピーされた各RespondentIDが含まれています - 2番目の列には数字が1から36までの数字が含まれています。 -11そのあとの列には、回答者/時間のsheet1からコピーされたデータが格納されます。

カウンタ: - N回答 数のカウンタ - エピソードの数のためのRカウンタ をこれらの36x11の領域は次のようにVBAスクリプトのロジックは

テストデータの「Response1-55」と命名されています - 応答がコピーされる行内のiカウンタ。

- (回答に始まるN = 1)>各応答について
- >最初のエピソード(9、R = 1から開始)を選択
--->各エピソードについて
--- >開始、終了、および間隔の時間を読み取る
---> i =開始からi =終了r番目のエピソードのn行目から関連するセルをコピーする
--->これらのセルを現在のエピソードのEndTimeに到達したら、
- >エピソードのyoあなたはEndTimeとして36を持っていて、次の応答に行くか、あなたがエピソードを使い果たすまで続けます。
- >次の応答

コードのデバッグではまさにこれを行うようです。

しかし、テストシートでvbaスクリプトを実行すると、エピソード1と2でのみ動作します。エピソード3と4からのデータはコピーされません。その場所には何もコピーされず、コピーされたデータはすべての点で正しいです。どの時点でもエラーメッセージはありません。

なぜこのようなことが起こっているのか誰かが示唆できたら、私は彼らに実際の教会を建てます。答えはここに追加することもできます:https://stackoverflow.com/questions/119323/nested-for-loops-in-different-languages VBAのセクションはまだありません。

テストシートへのリンクはこちら:コードの関連部分を開示することをここに

Sub PopulateMedia() 
    Application.ScreenUpdating = False 

    'Count the total number of response rows in original sheet 
    Dim Responses As Long, n As Integer, i As Integer, r As Integer 
     Responses = (Sheets("Sheet1").UsedRange.Rows.Count - 3) ' equals 55 in test sheet 

    'For each response... 
    For n = 1 To Responses 
     i = 1 'Reset i for new response 
      Dim curr_resp As Range 
       Set curr_resp = Sheets(2).Range("Response" & n) 'Define a range containing all response data 

      For r = 1 To 9 'For each episode... 
       Dim curr_ep As Range 'Define a range containing episode data for all responses 
        Set curr_ep = Sheets(1).Range("episode" & r) 

       Dim Stime As Integer, Etime As Integer, Itime As Integer 'Variables contain start, end and inter-episode times 
        Stime = curr_ep.Cells(n, 1) 
        Etime = curr_ep.Cells(n, 17) 
        Itime = curr_ep.Cells(n, 19) 

        For i = Stime To (Etime + Itime) 'for each time-slot... 
         If i <= Etime Then 
          Dim a As Variant 
          a = curr_ep.Range(curr_ep.Cells(n - 3, 1), curr_ep.Cells(n - 3, 11)) 
          curr_resp.Rows(i) = a 'Copy data from above current episode to current response for slots between Stime and Etime 
         End If 
        Next i 
       If Etime = 36 Then Exit For 
      Next r 
    Next n 

    Application.ScreenUpdating = True 
End Sub 

あるhttp://dl.dropbox.com/u/41041934/MrExcelExample/TornHairExampleSheet.xlsm

、私はすでに、VBA copy from a union of two ranges to a row of another rangeをこのサイトから、このプロジェクトの助けを持っていたが、それ以来、コードは少し変更されており、これは別の問題です。

もう一度、このようなご支援をいただき、ありがとうございます。私はこれを何時間も見つめていて、どこにエラーがあるのか​​見ていません。すべてのガイダンスは非常に高く評価されています。

+1

あなたはいくつかの段階でスプレッドシートの全体のデザインを再考することをお勧めします - という名前の使用すると、あなたはそれがデバッグにエラーが発生しやすいと困難なやり方範囲(あなたが気づいているように!)。 Excelは表形式のデータですばらしいものです.9つの別々の範囲を持つ代わりに、たとえば、エピソードの番号を含む追加の列を持つ1つのブロックを持つことができます。この単純な変更は、可読性とコードを大幅に改善します。 – assylias

+0

フィードバックをもう一度お寄せいただきありがとうございます。シートは実際にはプログラムによって生成されるので、混乱のいくつかがありますが、範囲を使用するのではなく、選択範囲をオフセットすることを意味します。現在の方法はとても近いですが、完全に機能しない場合は、提案されている方法を使用します。その場合、私はあなたにそれを答えるように頼むようにメッセージを出して、それを受け入れることができます。これをもう一度見ていただきありがとうございます。とても有難い。 – TornHair

答えて

5

私はこれをコメントとして投稿しますが、これは長すぎます。だからここでは、私はあなたの範囲の参照が問題

次のコードは、カットダウン、あなたのコードのバージョン

curr_epの名前付き範囲であると思います、クエリ/潜在的な解決策として

ですエピソード1。これは、の範囲のアドレスを持っているあなたは、この構文を使用して範囲を設定しているaバリアントをループ
a = curr_ep.Range(curr_ep.Cells(n - 3, 1), curr_ep.Cells(n - 3, 11))
同等である$Y$4:$AQ$58

あなたが実際にAW2:BG2を見ていることを意味するa = curr_ep.Range("Y2:AQ2")

ではないY2:AQ2私はあなたが意図したと思われるもの、つまりあなたが意図しないオフセットでビルドしていると思われるものです

Sub PopulateMedia() 
    n = 1 
    r = 1 
    Dim curr_ep As Range 
    Dim curr_test As Range 
    Set curr_ep = Sheets(1).Range("episode" & r) 
    Set curr_test = curr_ep.Range(curr_ep.Cells(n - 3, 1), curr_ep.Cells(n - 3, 11)) 
End Sub 

enter image description here

+1

コードを1行ずつ順番に表示する方法がわからない場合など。上記の黄色のバーを取得するには、マクロの解析に関するアドバイス(http://www.excel4business.com/videos/analyzing-macros-error-handling.php)に従ってください。基本的に、ブレークポイントを例えば"Next n"では、コードがrループを終了するときにさまざまな変数/コンポーネントを評価することができます –

+0

コメントありがとうございます。私はその方法でコードをステップ実行しましたが、上記の答えが示すようにレンジ変数のアドレスをチェックする方法はわかりませんでした。私は上記の答えはそれをクラックしたと思う:ループカウンタは、デバッグが示したように正しく動作している間違ったエピソードからコピーします。リンクをありがとう、私は今それを表示します。 – TornHair

+0

ありがとうございます、私は範囲を作って、示されているようにデバッグでそのアドレスを見てオリジナルをチェックしました、オフセットはまさに何が起こっているのですか?あなたの例でcurr_test行の設定は、現在のエピソードのn行目から3列目から11列目を選択すると考えました。今問題が明らかになったので、私はそのオフセットを導入しているものを探します。代替ソリューションのための助けと@assyliasを本当にありがとう。 – TornHair

関連する問題