Не могу получить данные из массива

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
konst
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 22
Зарегистрирован: 10.10.2007 (Ср) 12:23

Не могу получить данные из массива

Сообщение konst » 02.06.2008 (Пн) 0:04

В процедуре Form_Load производится переназначение двумерного массива Teplovyd (As String, нумерация элементов массива с единицы) и заполнение его данными (из ini-файла):
Код: Выделить всё
        ReDim Teplovyd(KolichKluch, KolichTokov)
       
        For i = 1 To KolichKluch
            For j = 1 To KolichTokov
                Teplovyd(i, j) = .GetKeyString("Ключ " & CStr(i) & " Ток " & CStr(j), "")
            Next j
        Next i

После заполнения в TextBox выводится:
Код: Выделить всё
        txtTeploKlucha.Text = Teplovyd(LastKey, LastCurrent)

Переменные KolichKluch(int), KolichTokov(int), LastKey(int), LastCurrent(int) - глобальные для формы, также берутся из ini-файла. Массив Teplovyd глобальный для всего приложения.

Всё нормально. Однако, после выбора в комбобоксе другого значения Key или Current (изменяется переменная LastKey или LastCurrent), при попытке вывода другого значения из массива Teplovyd в TextBox txtTeploKlucha, выдается ошибка "Run-time Error 9" (Subscript out of range):
Код: Выделить всё
Private Sub cmbCurrences_Click()

    LastCurrent = cmbCurrences.ListIndex + 1
    Call WriteIniStr("General", "Last Current", CStr(LastCurrent)) 'запись в ini-файл
   
    txtTeploKlucha.Text = Teplovyd(LastKey, LastCurrent)
   
End Sub

Где ошибка?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 02.06.2008 (Пн) 0:08

Нажми "Debug" наведи указатель мышки на LastKey, подержи, потом на LastCurrent.

Посмотри на всплывающие подсказки, говорящие о значениях этих переменных. (То же самое можно сделать, открыв pane Locals, но ведь так быстрее).

Посмотри, в какой из этих двух переменных содержится невалидный индекс.

Если окажется, что индексы и там и там - валидные, проверь размерности массива (в Locals, или вызовом UBound в Immediate pane)
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

konst
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 22
Зарегистрирован: 10.10.2007 (Ср) 12:23

Сообщение konst » 02.06.2008 (Пн) 0:27

Хакер писал(а):Нажми "Debug" наведи указатель мышки на LastKey, подержи, потом на LastCurrent.

Интересный способ! Нашел, что LastKey почему-то обнуляется. Почему - буду уже завтра разбираться. Спасибо!

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 02.06.2008 (Пн) 0:44

konst
Это не интересный способ. Это способ, которым все пользуются ежедневно и воспринимают его как что-то само собой разумеющееся. Это называется отладкой программы. Программисты VB могут гордиться тем, что VBIDE позволяет так делать, как я описал.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

konst
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 22
Зарегистрирован: 10.10.2007 (Ср) 12:23

Сообщение konst » 02.06.2008 (Пн) 1:11

Что-то я ничего не понимаю. Две совершенно одинаковые процедуры, а значения LastKey при наведении мышки во время отладки в первом случае "0", а во втором - правильное, то, что и записано в ini-файле.
Код: Выделить всё
'=======================================================================
' Изменение тока в комбобоксе
'=======================================================================
Private Sub cmbCurrences_Click()

    LastCurrent = cmbCurrences.ListIndex + 1
    Call WriteIniStr("General", "Last Current", CStr(LastCurrent))
   
'    txtTeploKlucha.Text = Teplovyd(LastKey, LastCurrent)
   
End Sub

'=======================================================================
' Изменение ключа в комбобоксе
'=======================================================================
Private Sub cmbKeys_Click()

    LastKey = cmbKeys.ListIndex + 1
    Call WriteIniStr("General", "Last Key", CStr(LastKey))
   
    txtTeploKlucha.Text = Teplovyd(LastKey, LastCurrent)

End Sub

Но "Run-time Error 9" выскакивает в обоих случаях. Размерность массива для начала выставил 3х2 (проверил с UBound - все правильно). Значения LastKey и LastCurrent менял и 1-1 и 2-2 и 1-2 и 2-1.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 02.06.2008 (Пн) 1:14

Debug-->Add watch

Ставишь Watch на свою переменную. Выбираешь все модули и процедуры. Ставишь "Break when value changes". Запускаешь и программа останавливается на всех местах, где значение твоей переменной меняется.

Таким образом ищешь место, где она обнуляется.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

konst
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 22
Зарегистрирован: 10.10.2007 (Ср) 12:23

Сообщение konst » 02.06.2008 (Пн) 1:55

Сделал, как ты написал, но при запуске окно Watches скрывается окном Быстрого выполнения (кстати - зачем оно нужно?), и при изменении LastKey (даже принудительно - из комбобокса), программа не останавливается. LastKey меняется (и записывается в ini-файл) правильно. Значения в конце FormLoad и в начале Private Sub cmbKeys_Click() - одинаковые, а в начале Private Sub cmbCurrences_Click() - обнулено.

Ну это одна история, но ведь в cmbKeys_Click значения переменных-то правильные, совпадающие со значениями в FormLoad. Но там значение из массива в текстбокс выводится правильно, а здесь выдает ошибку. Может, как-то по-другому отслеживать изменение значения в комбобоксе?

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 02.06.2008 (Пн) 8:48

А ты уверен, что у тебя LastKey объявлена один раз и глобально?
Весь мир матрица, а мы в нем потоки байтов!

konst
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 22
Зарегистрирован: 10.10.2007 (Ср) 12:23

Сообщение konst » 02.06.2008 (Пн) 12:22

Viper писал(а):А ты уверен, что у тебя LastKey объявлена один раз и глобально?

А, кстати, идея. Глобально для данного модуля. В других явно не применяется, но прийду домой, проверю...

konst
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 22
Зарегистрирован: 10.10.2007 (Ср) 12:23

Сообщение konst » 02.06.2008 (Пн) 20:00

Проверил - LastKey и LastCurrent объявляются один раз. Сделал объявление глобальным по проекту. К сожалению ничего не изменилось. Пишет Subscript out of range, хотя в массиве Teplovyd(LastKey, LastCurrent) переменные не выходят за рамки размеров массива :cry: .

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 03.06.2008 (Вт) 10:11

konst, значит надо отлавливать изменение величин, где-то что-то все же меняется. Watch тебе в помощь!
Весь мир матрица, а мы в нем потоки байтов!

konst
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 22
Зарегистрирован: 10.10.2007 (Ср) 12:23

Сообщение konst » 03.06.2008 (Вт) 12:04

Буду перелопачивать код. Спасибо за участие!

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 03.06.2008 (Вт) 12:29

Код: Выделить всё
option base 1

или начинай с 0 свой массив

konst
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 22
Зарегистрирован: 10.10.2007 (Ср) 12:23

Сообщение konst » 03.06.2008 (Вт) 12:54

Konst_One писал(а):
Код: Выделить всё
option base 1


Да у меня так и есть: Teplovyd (As String, нумерация элементов массива с единицы) . И в FormLoad всё отображается нормально, а та же самая строка
Код: Выделить всё
txtTeploKlucha.Text = Teplovyd(LastKey, LastCurrent)

с ТЕМИ ЖЕ ЗНАЧЕНИЯМИ LastKey и LastCurrent (проверял в Debug), в Sub cmbKeys_Click() вызывает ошибку Subscript out of range. Я уже не рассматриваю процедуру Sub cmbCurrences_Click() с теми строками кода (Ctrl-C - Ctrl-V), где та же самая переменная LastKey почему-то равна "0". Но это я пока закомментил. При выборе в комбобоксах других значений, они совершенно правильно записываются в ini-файл, и при перезапуске программы величина из массива правильно показывается в текстбоксе. А вот показ сразу после изменения у меня пока не выходит... Уже думаю - может VB переставить.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 03.06.2008 (Вт) 13:06

konst
Урежь проект до минимума, чтобы осталось только ошибкоопасное место, и выложи сюда.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

konst
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 22
Зарегистрирован: 10.10.2007 (Ср) 12:23

Сообщение konst » 03.06.2008 (Вт) 20:24

Вот - обрезал всё, что смог. Никаких дополнительных OCX не применял.
Вложения
Radiator_obrez.rar
(32.31 Кб) Скачиваний: 61

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 03.06.2008 (Вт) 20:35

konst
Эх...

У тебя по ходу выполнения первым выполняется обращение к массива, а вторым - ReDim.

Можешь заменить обращение к массиву на
Код: Выделить всё
MsgBox "Вот тут мы хотели обратиться к массиву. Вот тут у нас раньше возникала ошибка."

а ReDim на
Код: Выделить всё
MsgBox "Вот тут мы раньше делали ReDim."


Запустишь, тогда, и увидишь последовательность, в которой два этих действия у тебя выполняются.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

konst
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 22
Зарегистрирован: 10.10.2007 (Ср) 12:23

Сообщение konst » 03.06.2008 (Вт) 21:11

Хакер писал(а):konst
У тебя по ходу выполнения первым выполняется обращение к массива, а вторым - ReDim.

Вот этого-то я и не понимаю. В каком месте происходит первое обращение к массиву? Раньше ReDim я что-то ничего не вижу...

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 03.06.2008 (Вт) 21:13

konst
В том месте, в котором и происходит ошибка, происходит первое обращение к массиву. О оно происходит до РеДим-а. Поэтому, собственно, и возникает ошибка.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

konst
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 22
Зарегистрирован: 10.10.2007 (Ср) 12:23

Сообщение konst » 03.06.2008 (Вт) 21:24

Нет, ну я даже предположить не мог, что обращение к массиву происходит до FormLoad! Мир перевернулся! А где же мне сделать ReDim?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 03.06.2008 (Вт) 21:33

konst
С чего ты взял что "до"? Ничего подобного.

У тебя в Form_Load есть такая строчка:
Код: Выделить всё
cmbKeys.ListIndex = LastKey - 1                   'фокус комбо ключей


Собственно работа этой строчки кода и инициирует событие Click.
Стоит убрать эту строчку за ReDim, как всё начинает работать.

Но в целом скажу, что программа спроектирована ужасно.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

konst
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 22
Зарегистрирован: 10.10.2007 (Ср) 12:23

Сообщение konst » 03.06.2008 (Вт) 21:59

Хакер писал(а):konst
Стоит убрать эту строчку за ReDim, как всё начинает работать.

Спасибо за отзывчивость, и за реальную помощь! А насчет:
Но в целом скажу, что программа спроектирована ужасно.

Ты ещё не видел неурезанного кода! Я не программист, а инженер. Когда учился, кроме Фортрана с перфокартами ничего не было. Недавно попробовал VB. Оно как-то понравилось, и сейчас по вечерам делаю маленькие программки, облегчающие жизнь себе и коллегам. Может (и даже наверняка) они нерационально запрограммированы, но работают. Спасибо ещё раз!

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 03.06.2008 (Вт) 22:06

Клавиша F8 рулит. Спасибо F8, а не мне.

Я не программист, а инженер.

Влияет ли то, программист ты или инженер, на то, что вместо Key ты пишешь Kluch, вместо WarmRadiation - Teplovyd?

Влияет ли то, программист ты или инженер, на то, что вместо системного фона, у тебя используется [СЕРЫЙ]?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

konst
Начинающий
Начинающий
Аватара пользователя
 
Сообщения: 22
Зарегистрирован: 10.10.2007 (Ср) 12:23

Сообщение konst » 03.06.2008 (Вт) 22:33

Встречный вопрос (уже пошел offtop) - влияет ли то, как назовешь переменные, на работу программы? Мои переменные, как хочу, так и называю! :lol: Поначалу писал по-английски. А потом подумал - пишу для себя, а мой родной язык русский. И так достали всякие "Shop"-ы и т.п. на всяких вывесках. Если у меня инструмент, сделанный в Японии, это не значит, что работая им, я должен разговаривать по-японски. А компьютер (и среда проектирования) - тот же инструмент. И каким боком
вместо системного фона, у тебя используется [СЕРЫЙ]

относится к тому , что
Но в целом скажу, что программа спроектирована ужасно.

Я никоим образом ни на чем не настаиваю. Так, беззлобно огрызаюсь! Sorry за offtop! Спасибо!

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 04.06.2008 (Ср) 0:21

konst писал(а):Встречный вопрос (уже пошел offtop) - влияет ли то, как назовешь переменные, на работу программы? Мои переменные, как хочу, так и называю! :lol: Поначалу писал по-английски. А потом подумал - пишу для себя, а мой родной язык русский. И так достали всякие "Shop"-ы и т.п. на всяких вывесках.

Читать Шекспира в переводе Гоблина - это хуже, чем не читать Шекспира вообще. Даже если тебе нравится этот автор.

Писать kluch это хуже, это ещё большее издевательство над русским языком, - чем не писать на русском вообще. Даже если тебе нравится русский язык.

Здесь дело ещё вот в чём. Во многих областях традиционно используется какой-то один язык. В медицине - латынь. В технике - немецкий. В музыке - итальянский.

В программировании традиционно используется английский язык. Надо считаться с этим.


И каким боком
вместо системного фона, у тебя используется [СЕРЫЙ]

относится к тому , что
Но в целом скажу, что программа спроектирована ужасно.

Элементарно. Программа плохо спроектирована, если работа с ней может стать невозможной при определённых косвенных (не влияющих на работоспособность самой программы) установках системы.

    Небольшое отступление.
    Вообще говоря, я (и многие другие) считают дурным тоном при создании приложений отходить от принципов проектирования интерфейсов для Windows и для каких-то элементов жестко задавать свой цвет, вместо того, чтобы пользоваться цветвами, установленными в системе.

    Программу вы делаете для пользователя, а пользователя может тошнит от цвета, который вы выбрали для такой-то кнопки. Умные люди сделали так, что пользователь, которого тошнит от таких-то цветов, может эти цвета сменить по собственному усмотрению. Или вдруг пользователь дальтоник, и не видит разницы между цветом фона кнопки и цветом текста на ней?

    Зачем же лишать его этой возможности, навязывая свой цвет?


Так вот. У тебя BackColor - свой, а ForeColor - системный. Почему-то ты не рассматриваешь такой ситуации, что пользователь поставит себе в настройках цветовой схемы цвет текста -- серый, а цвет фона -- чёрный. При этом в твоей программе текст в тексбоксах станет ничитаем -- чтобы его прочитать придётся его выделять.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Zenitchik
Постоялец
Постоялец
 
Сообщения: 369
Зарегистрирован: 21.12.2006 (Чт) 14:48

Сообщение Zenitchik » 04.06.2008 (Ср) 0:51

Не согласен.
Технари традиционно используют транслитерированные переменные. Это повышает читаемость кода для технарей. Утверждаю как инженер.
Key, Index и т.п. - вызывают стойкие ассоциации со строковыми и целочисленными идентификаторами в разного рода моделях данных.
Кстати, тепловое излучение это не то же самое, что тепловыделение.

А вот дизайнерские изыски, ИМХО, зло. Я за классический дизайн, диктуемый системной палитрой и стандартным видом контроллов.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 04.06.2008 (Ср) 1:02

Не согласен.
Технари традиционно используют транслитерированные переменные. Это повышает читаемость кода для технарей. Утверждаю как инженер.

Причём здесь код? Имелся в виду язык, используемый в технике. Вон, слова шуруп, кронштейн, букса, грунбукс, муфта - сплошь немецкие. В музыке - диез, бемоль -- итальяно-французские.

Все химики мира используют одни и те же химеческие обозначения. Названия химических элементов традиционно - латинские.

Это - традиции той или иной области.
В программировании свои традиции. В частности - использование английского языка. Потому я буду презирать язык Глагол и его авторов. Патриотизм / любовь к родному языку здесь не причём.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 04.06.2008 (Ср) 7:20

Zenitchik писал(а):Не согласен.
Технари традиционно используют транслитерированные переменные. Это повышает читаемость кода для технарей. Утверждаю как инженер.
Чушь! Причем полная. Современный инженер должен знать как минимум технический английский (да и разговорный не помешает), поскольку большинство програмных комплексов имеет англоязычный интерфейс. А если уж инженер является еще и программистом, то тем более. Так что читаемость кода при использовании переменных типа Kluch будет гораздо хуже,чем при использовании Key.
Zenitchik писал(а):Key, Index и т.п. - вызывают стойкие ассоциации со строковыми и целочисленными идентификаторами в разного рода моделях данных.
Ключ (Key) он и в Африке ключ. Ассоциации тут вовсе не причем. Главное чтобы смысл названия соотвествовал смыслу ее использования.
Весь мир матрица, а мы в нем потоки байтов!


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 87

    TopList