2016-04-10 7 views
2

私はVB.NETプログラムを持っていて、配列を使ってループしていて、どこの瓶が「コンベア」上にあるのか把握しようとしています。このプログラムのポイントは、VB.netとLabelsを使用してコンベアがどのように動作するかを視覚的に示すことです。説明するのは非常に難しいので、ベストを尽くします。限界に達したときに配列を監視してリセットする方法。 VB.net

Bottle_Number(10)Bottle_Position(128)

私は、コンベア上のすべての128回の停止で追跡したい10本のボトルがあります。

私たちは10本のボトルにしか収まらないコンベヤを持っています。私は10本のボトルのそれぞれの位置を追跡する必要があります。ボトル11が来たら、ボトル1が完成し、コンベアから外れることを意味します。したがって、ボトル11はボトル1になるので、ボトル1の位置を0にリセットし、ボトル11(ボトル1ではなく)を追跡しながらボトル2〜9の追跡を続ける必要があります。ボトル12が来たら、それはボトル2になり、ボトル2の位置を「0」にリセットしてすべてのボトルの追跡を続ける必要があります。

ご協力いただければ幸いです。

Public Class frmMain 
Dim Product_Position(10) As Integer 
Dim Inches_Per_Pulse As Integer 
Dim PulseNumber As Integer 
Dim Product_Counter As Integer 
Dim Product_Location(10) As Integer 
Dim Function1 As Integer 
Dim Function2 As Integer 
Dim Function3 As Integer 
Dim Function4 As Integer 
Dim Function5 As Integer 
Dim Function6 As Integer 
Dim Function7 As Integer 
Dim Function8 As Integer 
Dim Function9 As Integer 
Dim Function10 As Integer 
Dim Product_in_Tunel As Integer 
Dim test As Integer 
Dim Roll_OVer As Boolean 
Dim Product_Counter_Test As Integer 


Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click 
    lblStatus.BackColor = Color.Green 
    lblStatus.Text = "Conveyor Status: Running" 
End Sub 

Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click 
    lblStatus.BackColor = Color.Red 
    lblStatus.Text = "Conveyor Status: Off" 

End Sub 
Private replace_next As Integer 
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click 

    If Product_Counter = 10 Then 
     replace_next += 1 
     If replace_next > 10 Then 


      replace_next = 1 ' replace them in turn 1..10, then loop back to 1 
      Product_Position(replace_next) = 0 ' put initial position here 

     End If 
    End If 
    Product_Counter = Product_Counter + 1 

    If Product_Counter > 10 Then 
     Product_Counter = 1 
     Roll_over = True 
    End If 

    'MsgBox(Product_Counter) 
    'MsgBox(replace_next) 

End Sub 



Private Sub btnPulse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPulse.Click 

    Get_Location() 





End Sub 


Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    PulseNumber = "0" 
    Inches_Per_Pulse = "1" 
    Roll_OVer = False 
    'MsgBox("Test") 
End Sub 


Public Sub Get_Location() 
    'MsgBox(Product_Counter) 
    If Roll_OVer = True Then 
     Product_Counter_Test = 10 

     'MsgBox("i'm stuck here") 
    End If 


    If Roll_OVer = False Then 
     Product_Counter_Test = Product_Counter 
    End If 
    'MsgBox(Product_Counter_Test) 
    'MsgBox("am I here - Yes") 
    For test = 1 To Product_Counter_Test 

     'MsgBox("This works") 
     Product_Position(test) = Product_Position(test) + Inches_Per_Pulse 

    Next 

    PulseNumber = PulseNumber + 1 
    ClearLabels() 
    lblProduct1Position.Text = Product_Position(1) 
    lblProduct2Position.Text = Product_Position(2) 
    lblProduct3Position.Text = Product_Position(3) 
    lblProduct4Position.Text = Product_Position(4) 
    lblProduct5Position.Text = Product_Position(5) 
    lblProduct6Position.Text = Product_Position(6) 
    lblProduct7Position.Text = Product_Position(7) 
    lblProduct8Position.Text = Product_Position(8) 
    lblProduct9Position.Text = Product_Position(9) 
    lblProduct10Position.Text = Product_Position(10) 
End Sub 


Public Sub ClearLabels() 

    lblProduct1Position.Text = "" 
    lblProduct2Position.Text = "" 
    lblProduct3Position.Text = "" 
    lblProduct4Position.Text = "" 
    lblProduct5Position.Text = "" 
    lblProduct6Position.Text = "" 
    lblProduct7Position.Text = "" 
    lblProduct8Position.Text = "" 
    lblProduct9Position.Text = "" 
    lblProduct10Position.Text = "" 


End Sub 

Screen Shot of Form

パルスボタンが実際コンベア、各パルス(ボタンのクリック)を駆動されているものであるコンベアが前進していることを意味:

は、ここに私のコードです。

今すぐプログラムがボトル11になると、リセットされ、「新しい」ボトル(ボトル1)だけが前進します。残っているボトルは、最後に到達するまでインクリメントし続け、同じようにします。ポジションを0にリセットして、再びカウントを開始します。

+0

'Queue(of T)'、 'LinkedList of(T)'、 'List(Of T)'もFIFOコンテナとして機能することができます。小さなクラスラッパーは、厳密なサイズ制限のロジックを実装できます。 Option Strictを有効にする必要があります。 – Plutonix

答えて

2

私が理解する限り、11本のボトルがあれば、1本のボトルにリセットするのではなく、まだ10本のボトルがあり、そのうち1本を交換します。どちらが置き換えられるかを追跡するためには、2番目の変数が必要です。 だから代わりに:あなたのコンベヤーはFIFO(先入れ先出し)、そうではなく、常に、シフトインデックス再作成および/または再構築である

Private Replace_Next as Integer = 0 

Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click 
    If Product_Counter = 10 Then 
     Replace_Next += 1 
     If Replace_Next > 10 Then Replace_Next = 1 ' replace them in turn 1..10, then loop back to 1 
     Product_Position(Replace_Next) = .... ' put initial position here 
    Else 
     Product_Counter = Product_Counter + 1 
    End If 
End Sub 
+0

さて、私たちは他のボトルの追跡を続けていきたいと思います。したがって、ボトル1が最後に達したら、他のボトルを見て、どこにいるのかを確認する必要があります。 – Shmewnix

+0

このように考えてみましょう:コンテナには10本しか入れることができません。私は10本のボトルのそれぞれの位置を追跡する必要があります。ボトル11が来たら、ボトル1が完成し、コンベアから外れることを意味します。したがって、ボトル11はボトル1になるので、ボトル1の位置を0にリセットし、ボトル11(ボトル1ではなく)を追跡しながらボトル2〜9の追跡を続ける必要があります。ボトル12が来たら、それはボトル2になり、ボトル2の位置を「0」にリセットしてすべてのボトルの追跡を続ける必要があります。 – Shmewnix

+0

新しいボトルがボトル1に取って代わりますか?この場合、Product_Counterを10にしてProduct_Position(1)を変更してください。 –

2

Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click 
    Product_Counter = Product_Counter + 1 
    If Product_Counter > 10 Then Product_Counter = 1 
End Sub 

それはのようなものになるでしょう(=リセット?)の配列は、それが、それはFIFOであるように見えるようにするために、ネットはQueue(Of T)コレクションFIFOあるが含まれています。

LinkedList(Of T)も使用できる。プレーンなList(Of T)も機能しますが、追加/削除の頻度が高いと、配列を持つフードの下で同じ非効率なシフトが発生します。

唯一の問題は、小さなクラスラッパーで簡単に処理できるサイズ制限の適用です。私は彼らの位置以外のボトルについて興味深い、または識別可能な何かがあると仮定します。テストコードは、シーケンスIDと内容を使用します。

Friend Class Bottle 
    Public Property Contents As String 
    Public Property SequenceID As Int32 
    ' etc 
    Public Overrides Function ToString() As String 
     Return String.Format("{0}: ({1})", SequenceID.ToString("00"), Contents) 
    End Function 
End Class 

もっと関連性の高い情報が表示されている可能性があります。コレクションクラス:

Friend Class BottleQueue 
    Private mcol As Queue(Of Bottle) 
    Private lbls As Label() 
    Private MaxSize As Int32 = 10  ' default 

    Public Sub New(size As Int32) 
     MaxSize = size 

     mcol = New Queue(Of Bottle) 
    End Sub 

    Public Sub New(size As Int32, l As Label()) 
     Me.New(size) 
     lbls = l 
    End Sub 

    Public Sub Add(b As Bottle) 
     mcol.Enqueue(b) 

     Do Until mcol.Count <= MaxSize 
      mcol.Dequeue() 
     Loop 
     UpdateDisplay() 
    End Sub 

    Public Function Peek() As Bottle 
     Return mcol.ElementAtOrDefault(0) 
    End Function 

    Public ReadOnly Property Count() As Int32 
     Get 
      Return mcol.Count 
     End Get 
    End Property 

    Public Function Remove() As Bottle 
     Dim b As Bottle = Nothing 

     If mcol.Count > 0 Then 
      b = mcol.Dequeue 
      UpdateDisplay() 
     End If 

     Return b 
    End Function 

    Private Sub UpdateDisplay() 
     Dim n As Int32 

     If lbls Is Nothing OrElse lbls.Count = 0 Then 
      Return 
     End If 

     For n = 0 To mcol.Count - 1 
      lbls(n).Text = mcol.ElementAtOrDefault(n).ToString 
     Next 

     For n = n To lbls.Count - 1 
      lbls(n).Text = "(empty)" 
     Next 
    End Sub 

    Public ReadOnly Property GetQueue As Bottle() 
     Get 
      Return mcol.ToArray() 
     End Get 
    End Property 

End Class 

クラスには2つの表示手段が組み込まれています.1つはラベルセットを更新します。それはコレクションなので、コレクションタイプコントロールのために現在のコレクションを取得する方法も提供します(Listboxなど)。コレクション自体が「観測可能」なので、データソースとして使用することもできます。

また、手動で次のボトルをRemoveに提供します。特定のインデックス(例:Remove(3))から削除すると、Queueと対立するため、実装されていません。

テストコード:

' form level vars: 
Private BottleQ As BottleQueue 
Private BottleID As Int32 = 7 

' form load, passing the labels to use 
' using a queue size of FIVE for test 
BottleQ = New BottleQueue(5, New Label() {Label1, Label2, Label3, Label4, Label5}) 

アイテムの追加:

Dim material = {"Napalm", "Beer", "Perfume", "Pepsi", "Cyanide", "Wine"} 

' add new bottle with something in it 
BottleQ.Add(New Bottle With {.Contents = material(RNG.Next(0, material.Count)), 
      .SequenceID = BottleID}) 
BottleID += 1 

' clear and show the contents in a listbox: 
lbQueView.Items.Clear() 
lbQueView.Items.AddRange(BottleQ.GetQueue) 

BottleId任意内容がランダムである、7から始まります。ところで、materialは、私が今までに配列を使用する唯一の方法を示しています。内容が固定され、事前にわかっていれば。ほぼすべての場合、おそらく1つまたは複数のNETコレクションがより良い選択です。

これは観測可能なコレクションではないため(FIFOの性質と少し似ています)、毎回リストボックスをクリアする必要があります。それはラベル表示のようなクラスの内部にある可能性があります。結果:右側に

enter image description here

は、第5の順序で示されています。 3クリック後、結果が左に表示されます。すべて上に移動したものは3つ、3つの新しい項目が追加されています。

注:コンベアから/ Bottleが削除されたとき、このコードでは、ItemRemovedイベントが含まれていて、強制的に1つ追加するときに削除されたアイテム/ボトルを提供する可能性があります。それはおそらくケースですが、その質問には言及しません。

+0

これは素晴らしいと徹底的な答えでした。私はそれを感謝します。 – Shmewnix

関連する問題