2017-11-21 24 views
1

1つのシート(DataWS)のすべての行をループし、文字列が見つからない場合は他のシートを使用してコードを検索しますエラーが発生した場所に移動するコード。したがって、ワークシート上にパーツが見つからない場合は、(どこかに)移動します。 ワークシート上で文字列が見つかった場合は、DataWSが更新されます。または、コード内の変数が後で使用され、他のシートで見つかった行を参照します。オブジェクト変数またはブロック変数が設定されていません。エラーが発生しました。

Sub MM011_to_Data() 

Dim Dlr As Long, Dlc As Long, x As Long 
Dim DataWS As String, MMWS As String, OmitWS As String 


    On Error GoTo DataSheetInvalid 
     Sheets("Data").Activate 
     DataWS = Sheets("Data").Name 
    On Error GoTo 0 

    On Error GoTo MM011SheetInvalid 
     MMWS = Sheets("MM011").Name 
    On Error GoTo 0 

    On Error GoTo OmitSheetInvalid 
     OmitWS = Sheets("Omit Parts").Name 
    On Error GoTo 0 

'********************BELOW ARE VARIABLES IN THE DATA SHEET******************** 

Dim DStatuscol As Integer, DSupplySourcecol As Integer, DPOcol As Integer, DPOIcol As Integer, DPRcol As Integer 
Dim DPLOcol As Integer, DWillShipcol As Integer, DSOLIcol As Integer, DRelPNcol As Integer 

DStatuscol = Sheets(DataWS).Rows(1).Find("Status", lookat:=xlWhole).Column 
DSupplySourcecol = Sheets(DataWS).Rows(1).Find("Supply Source", lookat:=xlWhole).Column 
DPOcol = Sheets(DataWS).Rows(1).Find("PO#", lookat:=xlWhole).Column 
DPOIcol = Sheets(DataWS).Rows(1).Find("PO Item", lookat:=xlWhole).Column 
DPRcol = Sheets(DataWS).Rows(1).Find("PR#", lookat:=xlWhole).Column 
DPLOcol = Sheets(DataWS).Rows(1).Find("PLO", lookat:=xlWhole).Column 
DWillShipcol = Sheets(DataWS).Rows(1).Find("Will Ship", lookat:=xlWhole).Column 
DSOLIcol = Sheets(DataWS).Rows(1).Find("CC SO/LI", lookat:=xlWhole).Column 
DRelPNcol = Sheets(DataWS).Rows(1).Find("RELEASED PN", lookat:=xlWhole).Column 


'********************BELOW ARE VARIABLES IN THE MM011 SHEET******************** 

Dim MMSupplySourcecol As Integer, MMInvcol As Integer, MMPOcol As Integer, MMPOIcol As Integer, MMPLOcol As Integer, MMPRcol As Integer 
Dim MMPOShipDatecol As Integer, MMStatuscol As Integer, MMPNConcatcol As Integer 

MMPNConcatcol = Sheets(MMWS).Rows(1).Find("PN Concatenate", lookat:=xlWhole).Column 
MMSupplySourcecol = Sheets(MMWS).Rows(1).Find("Supply Source", lookat:=xlWhole).Column 
MMInvcol = Sheets(MMWS).Rows(1).Find("Inventory Qty", lookat:=xlWhole).Column 
MMPOcol = Sheets(MMWS).Rows(1).Find("PO Number", lookat:=xlWhole).Column 
MMPOIcol = Sheets(MMWS).Rows(1).Find("PO Item", lookat:=xlWhole).Column 
MMPLOcol = Sheets(MMWS).Rows(1).Find("Supply Work Order", lookat:=xlWhole).Column 
MMPRcol = Sheets(MMWS).Rows(1).Find("Requisition Number", lookat:=xlWhole).Column 
MMPOShipDatecol = Sheets(MMWS).Rows(1).Find("Supply Delivery Calendar Date", lookat:=xlWhole).Column 


'********************BELOW ARE THE VARIABLES IN THE OMIT SHEET******************** 

Dim OPNcol As Integer, OPNrow As Long 

OPNcol = Sheets(OmitWS).Rows(1).Find("Part Number", lookat:=xlWhole).Column 

'********************LOOP TO UPDATE THE DATA SHEET******************** 

Dim DConcatPNSO As String, MMConcatrow As String 
Dim SupplySource As String, PO_Number As String, PO_Item As String, PLO_WO As String, Requisition_Number As String, Supply_Del_Date As String 
Dim DPartNumber As String 

Dlr = Sheets(DataWS).Cells(Rows.Count, 1).End(xlUp).Row 
Dlc = Sheets(DataWS).Cells(1, Columns.Count).End(xlToLeft).Column 


    For x = 2 To Dlr 

'DConcatPNSO is the variable for the Data WS which concatenates the Released PN and the SO LI 
     DConcatPNSO = Sheets(DataWS).Cells(x, DRelPNcol) & " " & Sheets(DataWS).Cells(x, DSOLIcol) 
     DPartNumber = Sheets(DataWS).Cells(x, DRelPNcol) 

'If there is no sales order then skip and say no sales order (NSO) 
     If Sheets(DataWS).Cells(x, DSOLIcol) = "" Then 
      Sheets(DataWS).Cells(x, DSupplySourcecol) = "NSO" 
     GoTo Updated 
     End If 

'Checks to see if the part is on the Omit list 
    On Error GoTo NotOmit 
     OPNrow = Sheets(OmitWS).Columns(OPNcol).Find(What:=DPartNumber, lookat:=xlWhole).Row 
    On Error GoTo 0 

    If OPNrow > 0 Then 
     Cells(x, DSupplySourcecol) = "Omit" 
    GoTo Updated 
    End If 

NotOmit: 

     On Error GoTo PN_SO_NotFound 
      MMConcatrow = Sheets(MMWS).Columns(MMPNConcatcol).Find(DConcatPNSO, lookat:=xlWhole).Row 
     On Error GoTo 0 

'Hold all of the info from cells into variables 
      SupplySource = Sheets(MMWS).Cells(MMConcatrow, MMSupplySourcecol) 
      PO_Number = Sheets(MMWS).Cells(MMConcatrow, MMPOcol) 
      PO_Item = Sheets(MMWS).Cells(MMConcatrow, MMPOIcol) 
      PLO_WO = Sheets(MMWS).Cells(MMConcatrow, MMPLOcol) 
      Requisition_Number = Sheets(MMWS).Cells(MMConcatrow, MMPRcol) 
      Supply_Del_Date = Format(Sheets(MMWS).Cells(MMConcatrow, MMPOShipDatecol), "MM/DD/YYYY") 

'If the Supply Source is PO then do the below 
       If SupplySource = "PO" Then 
        Sheets(DataWS).Cells(x, DStatuscol) = SupplySource & " " & Sheets(MMWS).Cells(MMConcatrow, MMPOcol) _ 
        & " " & Sheets(MMWS).Cells(MMConcatrow, MMPOIcol) & " " & Format(Sheets(MMWS).Cells(MMConcatrow, MMPOShipDatecol), "MM/DD/YYYY") 
        Sheets(DataWS).Cells(x, DSupplySourcecol) = SupplySource 
        Sheets(DataWS).Cells(x, DPOcol) = Sheets(MMWS).Cells(MMConcatrow, MMPOcol) 
        Sheets(DataWS).Cells(x, DPOIcol) = Sheets(MMWS).Cells(MMConcatrow, MMPOIcol) 
        Sheets(DataWS).Cells(x, DWillShipcol) = Format(Sheets(MMWS).Cells(MMConcatrow, MMPOShipDatecol), "MM/DD/YYYY") 
       GoTo Updated 
       End If 

'If the Supply Source is PLO then do the below 
       If SupplySource = "PLO" Then 
        Sheets(DataWS).Cells(x, DStatuscol) = SupplySource & " " & Sheets(MMWS).Cells(MMConcatrow, MMPLOcol) 
        Sheets(DataWS).Cells(x, DSupplySourcecol) = SupplySource 
        Sheets(DataWS).Cells(x, DPLOcol) = Sheets(MMWS).Cells(MMConcatrow, MMPLOcol) 
       GoTo Updated 
       End If 

'If the Supply Source is PR then do the below 
       If SupplySource = "PR" Then 
        Sheets(DataWS).Cells(x, DStatuscol) = SupplySource & " " & Sheets(MMWS).Cells(MMConcatrow, MMPRcol) 
        Sheets(DataWS).Cells(x, DSupplySourcecol) = SupplySource 
        Sheets(DataWS).Cells(x, DPRcol) = Sheets(MMWS).Cells(MMConcatrow, MMPRcol) 
       GoTo Updated 
       End If 

'If the Supply Source is BPL then do the below 
       If SupplySource = "BPL" Then 
        Sheets(DataWS).Cells(x, DStatuscol) = SupplySource & " " & "Borrow Payback Loan" 
        Sheets(DataWS).Cells(x, DSupplySourcecol) = SupplySource 
       GoTo Updated 
       End If 

'If the Supply Source is QA then do the below 
       If SupplySource = "QA" Then 
        Sheets(DataWS).Cells(x, DStatuscol) = SupplySource & ", PO is " & Sheets(MMWS).Cells(MMConcatrow, MMPOcol) _ 
        & " " & Sheets(MMWS).Cells(MMConcatrow, MMPOIcol) & " " & Format(Sheets(MMWS).Cells(MMConcatrow, MMPOShipDatecol), "MM/DD/YYYY") 
        Sheets(DataWS).Cells(x, DSupplySourcecol) = SupplySource 
        Sheets(DataWS).Cells(x, DPRcol) = Sheets(MMWS).Cells(MMConcatrow, MMPRcol) 
       GoTo Updated 
       End If 


Updated: 

    Next x 

Exit Sub 

'****************ERROR HANDLING**************** 

DataSheetInvalid: 
MsgBox "The worksheet with the MS2 All Open Order Report should be titled ""Data""." & vbCr & vbCr & "Please rename the worksheet and restart this sub.", vbCritical, "Worksheet Name" 
Exit Sub 

MM011SheetInvalid: 
MsgBox "The worksheet with Cognos (MM011) data should be titled ""MM011""." & vbCr & vbCr & "Please rename the worksheet and restart this sub.", vbCritical, "Worksheet Name" 
Exit Sub 

OmitSheetInvalid: 
MsgBox "The worksheet with Omit Parts data should be titled ""Omit Parts""." & vbCr & vbCr & "Please rename the worksheet and restart this sub.", vbCritical, "Worksheet Name" 
Exit Sub 

PN_SO_NotFound: 
Sheets(DataWS).Cells(x, DSupplySourcecol) = "N/A" 
GoTo Updated 

End Sub 

だから、このコード内で、ファイル名を指定して実行時エラーを取得し続ける部分がエラーハンドラではこれらのいずれかのいずれかです。最初のループで

'Checks to see if the part is on the Omit list 
    On Error GoTo NotOmit 
     OPNrow = Sheets(OmitWS).Columns(OPNcol).Find(What:=DPartNumber, lookat:=xlWhole).Row 
    On Error GoTo 0 

    If OPNrow > 0 Then 
     Cells(x, DSupplySourcecol) = "Omit" 
    GoTo Updated 
    End If 

NotOmit: 

     On Error GoTo PN_SO_NotFound 
      MMConcatrow = Sheets(MMWS).Columns(MMPNConcatcol).Find(DConcatPNSO, lookat:=xlWhole).Row 
     On Error GoTo 0 

彼らは仕事、それが来るの両方その後のループには、エラーが出ます。

私はこのコードを使用し、これらのエラー修正するには:

Set OPNrng = Sheets(OmitWS).Columns(OPNcol).Find(What:=DPartNumber, lookat:=xlWhole) 
    If OPNrng Is Nothing Then 
     GoTo NotOmit 
    Else 
     OPNrow = OPNrng.Row 
    End If 

If OPNrow > 0 Then 
    Cells(x, DSupplySourcecol) = "Omit" 
GoTo Updated 
End If 

NotOmit: 

    Set MMConcatrng = Sheets(MMWS).Columns(MMPNConcatcol).Find(DConcatPNSO, lookat:=xlWhole) 
    If MMConcatrng Is Nothing Then 
    GoTo PN_SO_NotFound 
    Else 
    MMConcatrow = MMConcatrng.Row 
    End If 

「でのエラー後藤」構文が働いていなかった理由はありますが?なぜ私は理解できません。 また、私の持っているもの以外にも、それを行うためのよりよい方法がありますか?

さらに詳しいことを説明できれば、私はこれらの問題を抱えている部分とコードを分けた全体像をあなたに伝えようとしました。

+5

*良い方法がありますか? - **はい!! **。スパゲティスタイルの 'GoTo'ステートメントの代わりに、関数と組み込みのVBA(そして一般的なプログラミング)メソッドを使用してエラーチェックを行います。たとえば、[WorksheetExists](https://stackoverflow.com/questions/6688131/test-or-check-if-sheet-exists/#6688482)は、最初の数行を解決できます。また、コードをコンポーネントプロシージャに分割し、フロー制御を1つの手順で行うこともできます。あなたのコードは読みやすく、管理しやすくなります。 –

+0

いいですね。私はVBAの約4ヶ月ですが、文法はまだ分かりませんが、WorksheetExistsメソッドを覚えています。それをコンポーネントの手順に分解すると、それはどういう意味ですか?最後に、スパゲッティスタイルで、私はそれがどのように飛び跳ねるかを意味していると思いますか?私はこのことをすべて前向きに心がけています。 – Adije

答えて

3
PN_SO_NotFound: 
Sheets(DataWS).Cells(x, DSupplySourcecol) = "N/A" 
GoTo Updated 

これです。あなたはエラー処理のサブルーチンに入っています.VBAランタイムはエラー状態にあり、あなたはGoToです。

実行がPN_SO_NotFoundを打った後Updatedラベルになると、あなたがそれをリセットすることはありませんので、VBAがエラー状態でまだあります。だからあなたのコードを理解する限り、Updatedラベルはエラー処理サブルーチンの一部に過ぎません。

そして、それはそれはまだランタイムエラーを処理だと思っている間、エラー状態ですでにだので、それが遭遇するあらゆるOn Error文に耳を傾けることはないだろう。

Resume UpdatedGoTo Updatedを交換し、指がを越え、まあ、正直なところ、それは "働く" 必要があります。

ただし、ここではいくつかの重大なリファクタリングについては間違いなく考慮する必要があります。このようなスパゲッティコードは、深刻な一連のリファクタリングがなければ、いつでもすぐにデバッグすることが容易になりません。つまり、合計0 GoToのジャンプがあり、すべての手順が1つの画面に収まるときただ一つ。

+0

コメント/回答/アドバイスをありがとうと私の無知を言い訳が、リファクタリングのために、どのようにすることが最善の方法でしょうか?また、すべてのプログラミングが1つの画面に収まると言っていますか?または、私は個々のタスクごとにサブを持っていなければならず、サブを1つ呼び出す必要がありますか?これはおそらくプログラミングの幼児期であり、物事を行うための最善の方法やロジックを理解していないだけですが、助けてくれてありがとうございます。 – Adije

+0

@Adije一般的には、目的の後にプロシージャの名前を付ける必要があります。プロシージャの名前を見つけるのが難しい場合は、そのプロシージャには多すぎる責任があるためです。手順を破る場所を知るためには、大きな問題をより小さな問題に分解する必要があります。それぞれの小さな問題にはそれぞれ独自の懸念があり、これらのさらに小さな問題は、より多くのより小さな「私的な」手続きとなり得る。これを実行すると、「神の手続き」から手続き型の手続き型コード、そして最終的にオブジェクト指向に移行します。乗り物をお楽しみください! –

0

On Error GoTo 0のみを使用する代わりに、On Error GoTo 0 : On Error Goto -1の組み合わせを使用して、例外ハンドラとエラー状態の両方をリセットします。

関連する問題