【问题标题】:How to monitor array's and reset when limit is reached. VB.net如何监控阵列并在达到限制时重置。 VB.net
【发布时间】:2016-04-10 12:36:08
【问题描述】:

我有一个 VB.Net 程序,它遍历数组以试图找出瓶子在“传送带”上的位置。该程序的重​​点是直观地向员工展示输送机如何使用 VB.net 和 Labels 工作。这很难解释,所以我会尽力而为。

Bottle_Number(10) Bottle_Position(128)

我想在传送带上的所有 128 个站点跟踪 10 个瓶子。

我们有一个只能装 10 个瓶子的传送带。我需要跟踪 10 个瓶子中每一个的位置。一旦第 11 瓶开启 - 这意味着第 1 瓶已完成并离开传送带。所以,瓶子 11 变成了瓶子 1,所以我需要将瓶子 1 的位置重置为 0,并继续跟踪瓶子 2-9,同时跟踪瓶子 11(不是瓶子 1)。一旦瓶子 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

脉冲按钮实际上是在驱动传送带,每个脉冲(点击按钮)意味着传送带正在向前移动。

现在,一旦程序到达第 11 瓶,它就会重置并仅向前移动“新”瓶 (bottle1)。它应该继续增加剩余的瓶子,直到它们到达末端并对它们执行相同的操作 - 将位置重置为 0 并重新开始计数。

【问题讨论】:

  • Queue(of T)LinkedList(of T) 甚至 List(Of T) 都可以充当 FIFO 容器。一个小的类包装器可以实现严格限制大小的逻辑。您应该打开 Option Strict。

标签: arrays vb.net arraylist


【解决方案1】:

据我了解,一旦你有 11 瓶,你不想重置为只有一瓶,而是仍然有 10 瓶,并更换其中一瓶。您需要第二个变量来跟踪要替换的变量。 所以而不是:

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

应该是这样的:

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

【讨论】:

  • 嗯 - 我想确保我们继续跟踪其他瓶子。因此,如果第 1 瓶到达终点,我们仍然应该观察其他瓶子,看看它们在哪里。
  • 这样想:我们有一个只能装 10 个瓶子的传送带。我需要跟踪 10 个瓶子中每一个的位置。一旦第 11 瓶开启 - 这意味着第 1 瓶已完成并离开传送带。所以,瓶子 11 变成了瓶子 1,所以我需要将瓶子 1 的位置重置为 0,并继续跟踪瓶子 2-9,同时跟踪瓶子 11(不是瓶子 1)。一旦瓶子 12 出现,它就变成了瓶子 2,我需要将瓶子 2 的位置重置为“0”并继续跟踪所有瓶子。
  • 你需要一个单独的变量来存储要更换的瓶子,我想。我已经更新了我写的内容
  • 所以过程是将状态不完整的瓶子放在传送带上的 0 英寸处。使用脉冲按钮逐英寸移动传送带。当瓶子到达位置 1 时,位置 1 是沿传送带的 x 英寸数,对其执行功能。沿输送带移动和英寸等。当瓶子通过英寸数 128 时,瓶子的状态现在完成,它被从输送带上取下。所以现在你需要一个带有状态和位置以及唯一 ID 的瓶子结构、一个不完整瓶子的列表和一个传送带上的瓶子列表。= 和一个完整瓶子的列表
  • 将未完成瓶子列表中的瓶子添加到传送带上的瓶子列表中,完成后将其从列表中删除,并将其移动到已完成瓶子列表中。
【解决方案2】:

您的传送带是 FIFO(先进先出),因此与其不断移动、重新索引和/或重建(=重置?)数组以使其 看起来像 FIFO,Net 包含Queue(Of T) 集合这是先进先出

也可以使用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 个显示装置。一个更新一组标签。由于它是一个集合,它还提供了一种获取当前集合的方法,以便为集合类型控件,例如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 显示了我使用数组的唯一方式:当内容是固定的并且提前知道时。在几乎所有其他情况下,一种或另一种 NET 集合可能是更好的选择。

因为它不是一个可观察的集合(这与 FIFO 的性质有点不一致),所以每次都需要清除列表框。这可能是类内部的,就像标签显示一样。结果:

右侧,按顺序显示前5个;单击 3 次后,结果在左侧:所有内容都向上移动了 3 和 3 个新项目。

注意:如果使用此代码的代码需要知道何时/哪个Bottle 从传送带上移除,则该类可以包含一个ItemRemoved 事件,该事件提供在添加力一时刚刚移除的项目/瓶子。大概是这样,但问题没有提到它。

【讨论】:

  • 这是一个绝妙而彻底的答案。非常感谢。
猜你喜欢
  • 2016-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-02
  • 2011-12-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多