#vb.net #multidimensional-array
#vb.net #многомерный массив
Вопрос:
У меня есть две формы: Act9.vb и List.vb. Код в обеих формах приведен ниже. Я использую vb.net «4.7.2» в Visual Studio. Я уже некоторое время очень разочарован этой программой. По какой-то причине программа проверяет только новых клиентов на соответствие первому и второму клиентам, которые уже есть в списке. Например, если в списке есть следующие записи:
╔═════════╦═════════════╗
║ ClientA ║ 32423223343 ║
╠═════════╬═════════════╣
║ ClientB ║ 23422322343 ║
╠═════════╬═════════════╣
║ ClientC ║ 23423423423 ║
╠═════════╬═════════════╣
║ ClientD ║ 43533453333 ║
╠═════════╩═════════════╣
║ etc... ║
╚═══════════════════════╝
Затем, если я попытаюсь изменить ClientA или ClientB (нажав btnModify и затем введя «ClientA» /»ClientB» в поле ввода), тогда это сработает, но если я попробую то же самое с ClientC, D, E и т.д. это не так. Я получаю это сообщение: «Этот клиент не существует. Пожалуйста, попробуйте еще раз. »
То же самое с добавлением новых клиентов: это не позволит мне добавить ClientA или B дважды, но если я попытаюсь добавить клиент C еще раз, он не поймет, что он уже находится в многомерном массиве, и позволит мне добавить его во второй раз.
Если кто-то знает что-нибудь, что может помочь, пожалуйста, поделитесь. Заранее спасибо!
Public Class Act9
Public Clients(1, 1) As String
Public size As Integer = 0
Sub Add()
Dim tempClient As String
Dim tempTel As String
tempClient = InputBox("Please enter the clients name :", "Name")
If Duplicate(tempClient) Then
MsgBox("This client already exists")
Else
tempTel = InputBox("Please enter the client's phone number:", "Phone number")
Clients(0, size) = tempClient
Clients(1, size) = tempTel
size = 1
ReDim Preserve Clients(1, size)
End If
End Sub
Function Duplicate(ByVal tempClient As String) As Boolean
Dim output As Boolean = False
For i As Integer = LBound(Clients) To UBound(Clients)
If Clients(0, i) = tempClient Then
output = True
End If
Next
Return output
End Function
Private Sub BtnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
Add()
End Sub
Private Sub btnShow_Click(sender As Object, e As EventArgs) Handles btnShow.Click
List.ShowDialog()
End Sub
Private Sub btnErase_Click(sender As Object, e As EventArgs) Handles btnErase.Click
ReDim Clients(1, size)
List.lstClients.Items.Clear()
size = 0
End Sub
Private Sub btnModify_Click(sender As Object, e As EventArgs) Handles btnModify.Click
modify()
End Sub
Sub modify(Optional who As String = Nothing)
Dim change As Boolean = False
If who = Nothing Then who = InputBox("Please enter the name of the client you wish to modify:", "Modify")
For i As Integer = LBound(Clients) To UBound(Clients)
If Clients(0, i) = who Then
Clients(0, i) = InputBox("Please enter the new name for the client:", "Name")
Clients(1, i) = InputBox("Please enter the new phone number for the client", "Phone number")
change = True
Exit For
End If
Next
If change = False Then MsgBox("This client doesn't exist. Please try again.")
End Sub
End Class
Public Class List
Private Sub List_Load(sender As Object, e As EventArgs) Handles Me.Load
lstClients.Items.Clear()
For i As Integer = 0 To Act9.size - 1
lstClients.Items.Add(Act9.Clients(0, i) amp; vbTab amp; Act9.Clients(1, i))
Next
End Sub
End Class
Комментарии:
1. Это домашнее задание?
2. Честно говоря, многомерный массив является неоптимальной структурой для использования для такого рода данных. Рассмотрим
Dictionary(Of String, String)
3. @Craig Спасибо, спасибо. Это, вероятно, звучит глупо, но я не знал, как это сделать. Я посмотрел и попробовал. Это помогло мне найти и устранить проблему за считанные минуты. Это действительно полезный инструмент! Я не знаю, как выразить свою благодарность за то, сколько времени это сэкономит мне. Еще раз спасибо. =)
4. Я спросил, было ли это домашним заданием, главным образом потому, что оно изменяет данный совет; у вас, вероятно, есть такие параметры, как «необходимо использовать многомерный массив», что означает, что независимо от того, насколько мы умоляем вас изменить его (потому что это в основном дерьмовый способ хранения чего-либо, и я никогда в своей профессиональной жизни их не использовал, даже ни разу, после ухода из академии) вы не можете.
5. Я бы рекомендовал вызвать ваш метод isDuplicate, потому что он возвращает логическое значение. Вызов этого дубликата подразумевает, что переданный объект будет дублироваться
Ответ №1:
@Craig сказал мне использовать точки останова, которые являются идеальными инструментами для этого. Я очень благодарен за совет.
Вот как я в итоге заставил его работать должным образом:
Я заменил LBound и Ubound своей переменной «size» (которая уже занималась подсчетом размера моего многомерного массива).
Цикл For в «Дубликате» становится:
For i As Integer = 0 To size
If Clients(0, i) = tempClient Then
output = True
End If
Next
Тот, который находится в «Изменить становится:
For i As Integer = 0 To size
If Clients(0, i) = who Then
Clients(0, i) = InputBox("Please enter the new name for the client:", "Name")
Clients(1, i) = InputBox("Please enter the new phone number for the client", "Phone number")
change = True
Exit For
End If
Next
Ответ №2:
Причина, по которой ваш исходный код не сработал, заключается в том, что вы LBound / UBound в первом измерении, но ваш массив распространяется на второе измерение. Первое измерение имеет значение только от 0 до 1, поэтому вы проверяли только индексы второго измерения 0 и 1 (первые два элемента) для имени:
For i As Integer = LBound(Clients) To UBound(Clients)
Если вы используете
LBound(Clients, 2) to UBound(Clients, 2)
Он получит верхний предел второго измерения, а не первого. UBound использует индексацию на основе 1, тогда как VB использует 0. Если вы хотите то же самое на основе 0, вы можете использовать
Array.GetUpperBound(Clients, 1)
чтобы найти предел второго измерения
Другие советы:
- ваш метод modify допускает ту же ограничивающую ошибку
- если бы это было программирование 201, вы, вероятно, использовали бы Список (Client), Client — это класс, имеющий пару строковых свойств для name и tel, и переопределенный метод equals, который сравнивает имя входящего клиента, так что список.Содержит может использоваться для предотвращения дубликатов. В конечном итоге вы, вероятно, также переопределите GetHashCode и используете HashSet (клиента). И все это на самом деле было бы намного проще. Многомерные массивы обычно являются плохим решением для хранения.. ну .. все
- ваша
size
переменная является общедоступной; она должна иметь заглавную букву s - ваш метод modify — это метод; он должен иметь заглавную букву M. Все методы в .net имеют заглавные начальные буквы
- возможно, btnErase следует установить размер перед его переопределением
- ваш метод дублирования проверяет каждый элемент в массиве. Он продолжает проверку, даже если он уже нашел дубликат элемента. Вы можете пропустить ту часть, где вы создаете логическое значение и просто возвращаете True внутри If; ваши ключи всегда находятся в последнем месте, куда вы смотрите, потому что вы перестаете искать, когда их находите 🙂
- возможно, если вы реализуете метод findIndex, который принимает имя и возвращает индекс того, где находится этот человек, или -1, если он их не нашел, вы можете использовать его как для isDuplicate (вызовите findindex и верните true, если результат больше -1), так и для Modify (найдите индексчеловек и измените их или поместите сообщение Не найдено, если -1 приходит bac). Это означает, что у вас может быть только один метод, который выполняет поиск в массиве, и вы используете его дважды. Это означает, что вы не повторяетесь — принцип разработки программного обеспечения, которого мы стараемся придерживаться. На данный момент ваши методы duplicate и modify имеют один и тот же цикл (с одной и той же ошибкой)
Комментарии:
1. Спасибо за помощь. Это все отличные советы. У меня не было выбора использовать что-то другое, кроме многомерного массива, поскольку это было частью задания. Я понимаю, что это не очень хороший метод хранения. Еще раз спасибо за вашу помощь.