Мне дали задание изменить проект VB6. Ничего особо серьезного, добавление пары форм и исправление нескольких ошибок по большей части. В проекте используется SQL Server (если это имеет какое-то значение).
Мой опыт в программировании был VB / C# .NET, PHP, C++ и в основном MySQL, хотя я использовал SQL Server в гораздо меньших масштабах. Какой совет может дать мне кто-нибудь или ресурсы для программирования на VB6. Прошло несколько лет с тех пор, как я работал над VB .NET, и хотя я могу читать код VB6 и понимать, что происходит, я не уверен, насколько хорошо я смогу начать писать и / или модификация без шанса что-либо сломать.
Какой совет могут дать другие? Любые ресурсы и / или истории были бы замечательными. Не стесняйтесь вносить то, что вы считаете актуальным, но я не упомянул.
Спасибо!
Отличная книга о том, как хорошо делать vb6: amazon.com/…





Пожалуйста, не используйте "При ошибке возобновить следующий".
еще один +1 - худшая "языковая особенность" когда-либо ...
или («вздрогнуть») заявление «Стоп».
Я любил использовать «Конец» в крайнем случае.
Вероятно, он уже там, но убедитесь, что Вариант Явный находится в верхней части всех файлов. Он принудительно объявляет переменную и снижает вероятность непреднамеренной опечатки при создании переменной на лету.
Я знаком с Option Explicit из VBScript и VB .NET. Однако я уже просмотрел некоторые исходники, и они с таким же успехом могли выбросить область видимости переменных из окна.
Это единственный совет, к которому здесь можно без недоверия. Остальное варьируется от чепухи до чисто токсичного. : - /
Что ж, в зависимости от того, насколько плохая база кода, включение Option Explicit может сразу означать огромный объем работы только для компиляции. Фактически, единственные люди, которые этого не сделали, - это те люди, которые создали все беспорядки VB.
Забавно, что весь мир без ума от языков, которые позволяют использовать переменные без их объявления ...
@ Эдуардо Я согласен. И утиная печать тоже. После нескольких лет уговоров Option Strict перешла на VB, чтобы позволить нам избежать злого принуждения (утиная типизация). Видимо в первую очередь виноват Джоэл joelonsoftware.com/items/2009/03/09.html
VB6 имеет неработающую систему типов - на самом деле он имеет две системы типов, которые не полностью совместимы. Архитектурно VB4-6 представляет собой довольно тонкую оболочку над COM и использует систему типов COM. Предыдущие версии VB имели свою собственную систему типов, которая представляла собой нечто среднее между традиционным BASIC и C. Эти два понятия не могут быть свободно смешаны и сопоставлены.
Здесь нет наследования и реальной обработки исключений, поэтому ожидайте написания большого количества шаблонного кода для обработки ошибок и повторения основных функций формы, повторяющихся снова и снова. Именно здесь VB получает репутацию разработчика программного обеспечения, работающего по принципу вырезания и вставки.
Некоторые из типов, которые вы можете объявить в VB, не «совместимы с автоматизацией», что означает, что они не могут быть сериализованы через границу COM или сохранены в Variant (подробнее об этом позже). Эти типы относятся к временам, предшествующим VB4-6, когда VB не поддерживал COM. Один из этих типов - это тип записи (например, структура c), имя которого ускользает от меня, поэтому расширяемая коллекция или ассоциативный массив структур (что является естественной вещью, которую можно захотеть сделать) невозможны. Определение класса (см. Ниже) возможно, но несколько неуклюже.
VB не поддерживает многопоточность, и обходные пути для этого имеют много подводных камней. Первый из них может вас укусить, если вы занимаетесь трехуровневой разработкой с использованием MTS или COM +. Создание модуля VB фактически создает за кулисами одноэлементный COM-объект. Он будет жить в собственной однопоточной квартире. Квартиры - это, по сути, легкие работающие COM-серверы с механизмом сериализации / десериализации (называемым Message Pump), где вызовы сериализуются и помещаются в очередь для одного потока. Если вы сделаете (на первый взгляд) разумную вещь и попытаетесь модулировать свой код, вы создадите горячие точки на среднем уровне. Решение: больше вырезать и вставить.
Вторая важная проблема заключается в том, что сборка мусора в COM довольно проста - это простой механизм подсчета ссылок. Это означает, что компоненты COM, которые выходят из строя или по какой-то причине не убирают после себя утечку памяти. Помните, как VB6 - это всего лишь тонкий слой над COM? Эта тесная связь означает, что вы должны быть довольно осторожны при использовании кода управления пользовательским интерфейсом, который содержит ссылки на элементы управления, автоматизацию OLE во внешних приложениях (например, Excel) или что-либо еще, что устанавливает ссылки. VB неплохо умеет делать скрытые вещи за вашей спиной и не знает, когда убирать за собой. Это также источник циклических ссылок, генерируемых за кулисами. Сделайте это неправильно, и это приведет к утечке ресурсов - вы должны быть осторожны с этим.
Другая важная проблема - это варианты. Лучшее описание типа Variant, которое я видел, - это «Ячейка электронной таблицы». Это может вызвать массу неприятностей, особенно в случае с вариантами массивов. Многие API работают только с вариантами или имеют случайные части, которые используют варианты (Excel делает это часто), поэтому вы не всегда сможете их избежать. Если вы сериализуете материал через границы COM (например, несколько отключенных наборов записей), вы скоро научитесь ненавидеть массивы вариантов.
Вы, вероятно, обнаружите, что система типов VB настолько сломана, что самый простой способ поддерживать нетривиально сложную структуру данных - это создать библиотеку, которая кодирует ее в строку и по существу сериализует и десериализует ее. Сложные структуры данных в приложении VB6 почти не нужны.
Наконец, после использования инструментария GUI для VB6, вы узнаете, насколько команда, создавшая WinForms, извлекла уроки из ошибок команды VB6.
Хотя это продвигалось как простое и легкое в использовании, создание нетривиального приложения на VB, не создавая беспорядка, было намного сложнее, чем казалось, из-за всех архитектурных недостатков и мелких ошибок. Это неплохой пример Закон дырявых абстракций. Спольски.
Appleman Разработка компонентов COM / ActiveX в Visual BASIC 6 довольно хорошо описывает все тонкости взаимодействия COM с VB6. Еще он неплохо справился с Программирование Win32 и VB..
P.S. (спасибо, что напомнили мне, Даока), если вы обнаружите, что кто-то использовал On Error Resume Next, у вас есть мое разрешение на их использование задница.
Все это было сказано, и я и другие программисты сделали с VB6 довольно удивительные вещи! :) Но спасибо Будде за .net!
Бог с ним. Когда меня спрашивали о .Net, я говорил: «Представьте себе версию VB, которая не отстой».
Эй, давайте не будем забывать, что многие из хороших частей Visual Studio впервые появились на VB.
@Terry То, что что-то было использовано для создания чего-то хорошего, не делает инструмент хорошим. То есть пирамиды строили не с помощью кранов и бульдозеров. Чтобы сделать что-то хорошее, нужен хороший программист, хороший язык помогает. Я не говорю ничего хорошего или плохого о VB, просто рассуждения
Скорее используйте on error resume next, чем on error goto X, но ВСЕГДА сразу выявляйте ошибки, а затем сбрасывайте обработку ошибок.
Пример:
...
On Error Resume Next
oDbConn.Open sDbConnString
Select Case Err.Number
Case &H80004005
MsgBox "Cannot connect to SQL-server, check your settings."
frmSettings.Show
Exit Sub
Case Else
ShowErrorAndQuit Err
End Select
On Error Goto 0
...
Ах, малоиспользуемая псевдопроба Visual Basic. Красивый.
Для одной строки кода, подобной этому простому примеру, это попытка поймать похоже, но на самом деле она требует отдельной проверки Select Case Err.Number после строки кода каждый, которая потенциально может вызвать ошибку! Для реального кода лучше использовать On Error Goto X и проверить Select Case Err.Number на теге X. Если вы хотите продолжить с того места, на котором остановились, запустите Resume Next после кода обработчика ошибок. В VB6 нет простого механизма, который мог бы полностью имитировать способ обработки исключений методом try-catch.
Люди, которые написали здесь и сказали, что «При ошибке возобновить следующее» - это худшая языковая функция, совершенно неправы.
Худшая языковая особенность когда-либо была "При ошибке возобновить". Поверьте мне в этом.
Для людей с нарушенным VB сообщение On Error Resume Next означает «что-то пошло не так, переход к следующей строке». При возобновлении ошибки означает «что-то пошло не так, лучше попробуйте снова и снова, и снова, и снова, и ...».
Вы прочитали мой ответ полностью?
Я думаю, вы плохо понимаете, что такое «Возобновить при ошибке». Если что-то не так, он переходит на следующую строку без предупреждения. При возобновлении ошибки требуется что-то после резюме ... "перейти" или "возобновить" ... не ничего ... как вы говорите
Я понимаю, о чем вы говорите. Когда я сказал: «Что-то пошло не так, переходите к следующей строке», я не имел в виду, что вас каким-либо образом уведомили об этом - вы этого не сделали.
И «Возобновление при ошибке» было менее известным, чем «Возобновление при ошибке», но на самом деле вы могли использовать Возобновление без указания каких-либо аргументов, что заставило бы VB повторно выполнить строку, которая изначально вызвала ошибку.
См. Здесь: developerfusion.com/article/1741/handling-errors-in-vbvbavbs asp /… Вы действительно когда-нибудь программировали на Visual Basic до .NET?
Само по себе резюме не было самой плохой идеей, но резюме в случае ошибки имело место. За более чем 10 лет профессионального программирования на VB я так и не нашел ему достойного применения. С другой стороны, при возобновлении ошибки есть свое место. Я все еще хихикаю над поддельным письмом с набором функций VB6, в котором утверждается, что они собираются ввести «Global On Error Resume Next».
Согласен, что On Error Resume плохой. Но я думаю, причина, по которой это можно сделать, заключается в том, что On Error - это одна команда, требующая указания некоторого действия, которое может быть любым из Resume, Resume Next, Goto X -> Который на месте также может быть запущен сам по себе без префикса On Error . Оператор Resume можно использовать отдельно в секции обработчика ошибок (инициированной On Error Goto X) после исправления состояния, вызвавшего ошибку, и повторной попытки - и это действительно имеет смысл!
Я в основном использовал автономный оператор Resume только при отладке, имея точку останова в коде обработчика исключений, а затем добавляю Resume во время отладки, чтобы точно определить фактическую команду, которая вызвала ошибку, или возобновить после установки допустимого состояния в окне Immediate.
Лично мне нравится On Error goto ErrorHandler с обработчиком ошибок внизу каждой функции.
Не забывайте никогда не включать круглые скобки при вызове метода, если вы не собираетесь смотреть на его возвращаемое значение. Этого легко избежать в методах с одним аргументом, но иногда это укусит вас, поскольку передача (переменная) - это нет, то же самое, что и передача переменной.
Люди, пишущие на VB, не совсем понимали, предпочитают ли они массивы с индексом 0 или массивы с индексом 1. Вы можете использовать UBound / LBound, чтобы проверить, где начинается и где заканчивается массив.
Не используйте «сравнение текста» для преобразования регистра. Сравнение строк как текста - это не просто игнорирование регистра. Просто преобразуйте одну или обе строки в верхний регистр.
Проекты-> Свойства-> Удалить информацию о неиспользуемых элементах управления ActiveX должны быть отключены, если вы вызываете их во время выполнения.
Инструменты-> Редактор-> Автоматическая проверка синтаксиса. Если не привык, может выключить.
Инструменты-> Редактор-> Требовать объявление переменной. На.
Инструменты-> Среда-> При запуске программы-> Сохранить изменения. Если он выключен, ваша программа не будет сохранена, даже если вы ее запустите.
Используйте Run-> Start With Full Compile, Not Run-> Start, чтобы запустить свой код.
Примечание: Tools->Editor->Auto Syntax Check просто указывает, следует ли сразу получать сообщение об ошибке при переходе на другую строку. Это очень раздражает, если вы пишете что-то временное и хотите скопировать код из другого места. Если этот параметр отключен, среда IDE по-прежнему сразу сообщает вам, что что-то не так, отмечая это красным, но избавляет вас от раздражающего окна сообщения. Так что да - вы должны выключить это!
Примечание 2: Run->Start With Full Compile скомпилирует весь ваш код до, он запустит вашу программу. Run->Start просто запустит ваш код и скомпилирует во время выполнения то, что необходимо, что может скрыть потенциально ошибки компиляции в частях кода, которые вы не запускаете. Так что да, еще раз об этом (просто чтобы объяснить, почему ...)
Не используйте On Error Resume Next без крайней необходимости (есть некоторые уникальные случаи, например, окончательная очистка после обработки ошибок или проверка существования элемента VB Collection, но обычно вам это не нужно внутри тела функции).
Реализуйте правильную обработку ошибок, не используйте более одной точки выхода, не используйте однострочники If-Then, используйте блок Case Else, не используйте Subs - что-то вроде следующего очень простого скелета функции:
Private Function MyFunc() As Boolean
On Error Goto ErrHandler
''some code here
If SomeBadExitConditionIsSet Then
GoTo FuncExit
End If
''some more code here
MyFunc = True
FuncExit:
''kill error handling to avoid error cycling
On Error Resume Next
''cleanup code here - you need to check Err.Number after critical operations!
''single exit point
Exit Function
ErrHandler:
''you can insert local specific error processing here, do not forget save Err.Number etc
''there is possibility to raise errors to caller function,
''but in this function we do not do that
Select Case MyGlobalErrHandler(Err.Number, Err.Description)
Case eRetry
Resume ''this is useful while debugging - good place to "Set Next Statement"
Case eIgnore
Resume Next
Case eCancel
Resume FuncExit
Case Else
Resume FuncExit
Select End
End Function
Так как я набрался опыта в Visual Basic (в резюме написано, что VB3-6 10+ лет), я попытаюсь ответить на ваш вопрос чем-то другим, кроме «При ошибке возобновить следующее» - отстой (что он делает, но вы найдете это повсюду, или не будешь, что еще хуже). Вот что вы можете сделать:
Что касается Visual Basic в целом, я бы сказал, что не верю анти-шумихе. Это был язык, допускающий хороший или плохой код, как и любой другой. И помните, что все ужасные программисты VB теперь ужасные программисты на C#.
Я не совсем согласен с этим. VB - единственный язык, с которым я когда-либо работал (за возможным исключением SQL), который имел архитектурные ограничения - в основном из-за его тесной связи с COM - что затрудняло написание хорошего кода.
VB 3 определенно имел некоторые архитектурные ограничения (без классов - понятия не имею, как я что-то делал без классов).
+1 Приятно видеть реалистичные комментарии о VB. Это никогда не было «лучшим», но и далеко не худшим.
Я бы сказал, опубликуйте свои проблемы в группе Microsoft VB6, все еще поднимаясь с активный VB6 разработчиков groups.google.co.uk/group/…
@MarkJ: Я думаю, вы имели в виду «все еще занимаюсь СУХОЙ с активными разработчиками VB6». :)
+1 за «все ужасные программисты VB теперь ужасные программисты на C#».
Правильно о том, чтобы объединить проекты в как можно меньшее количество.
Если ваше приложение использует проекты ActiveX DLL, убедитесь, что это именно та ситуация, чтобы свести к минимуму ад DLL.
Несмотря на отсутствие наследования, вы обнаружите, что VB6 может реализовывать многие общие шаблоны объектно-ориентированного проектирования. Если вы посмотрите в Шаблоны проектирования, Элементы многоразового объектно-ориентированного программного обеспечения, вы увидите, что большинство шаблонов подразумевает реализацию интерфейса, а не наследование поведения. Они говорят об этой проблеме, начиная со страницы 16.
Строго типизированные коллекции непросто реализовать. Вы пишете коллекцию со всем, включая свойство Item только для чтения. Когда вы закончите, вам нужно будет нажать {F2} и открыть обозреватель объектов. Найдите созданный вами класс коллекции и щелкните правой кнопкой мыши элемент.
Вам нужно будет
Тогда Item станет свойством по умолчанию, и коллекция типов Strongly будет действовать должным образом.
Чтобы включить использование For Each в классе коллекции, вам нужно добавить это
Public Property Get NewEnum() As IUnknown
Set NewEnum = mCol.[_NewEnum]
End Property
С mCol - это имя переменной частной коллекции
Снова используйте обозреватель объектов и щелкните правой кнопкой мыши NewEnum.
Вам нужно будет
Помните, что Integer является 16-битным, а Long - 32-битным. Я рекомендую объявить большинство целочисленных переменных как Long. Раньше это имело значение для скорости и объема памяти, но с сегодняшними компьютерами лучше просто использовать Long и не беспокоиться о превышении ограничений.
Как предложено в другом месте, используйте Option Explicit.
Visual BASIC 6 очень хорош в неявном преобразовании типов. У вас есть функции преобразования серии Cxxx, если вы хотите быть уверены.
Вариант лучше, чем объект .NET, при работе с разнообразным диапазоном типов объектов, включая классы. Вы можете найти это полезным, если вам нужно создать настраиваемую форму для работы с базой данных, и пользователь может выбрать, какую таблицу использовать для этой формы. Использование Variant упрощает работу с тем фактом, что поля разных типов для разных таблиц.
Visual Basic 6 можно использовать для создания многоуровневых приложений. Формы могут реализовывать интерфейсы, такие как классы.
Помните, что элементы управления ActiveX запускаются при компиляции и редактировании формы. Это может вызвать разные странности, если вы этого не осознаёте. Это особенно проблематично, если у вас есть собственные элементы управления ActiveX.
Общая мудрость при объявлении объектов заключалась в том, чтобы избегать использования «Dim myObj As New MyClass». Вместо этого используйте «Dim myObj As MyClass» и явно создайте экземпляр объекта, когда это необходимо, с помощью «Set myObj = New MyClass». Первый метод не создает экземпляр объекта, когда встречается «Dim», но автоматически делает это при первой ссылке на одно из свойств или методов объекта. Это потребовало дополнительных накладных расходов со стороны среды выполнения, поскольку она должна проверять, существует ли объект перед каждой ссылкой на свойство / метод. Кроме того, у этого метода объявления объекта были и другие причудливые побочные эффекты. Например, если для myObj установлено значение Nothing, и программа встречает другую ссылку на него, автоматически создается новый экземпляр. Скорее всего, если такая ситуация возникнет, с вашей программой что-то не так, но не будет сгенерирована ошибка, сообщающая вам, что ваш объект не существует, что может привести к некоторым трудно обнаруживаемым ошибкам. Как правило, лучше явно создавать и уничтожать экземпляр объекта самостоятельно, используя синтаксис «Set = New». Сторонники синтаксиса «Dim As New» обычно ссылаются на лучшую читаемость, но иногда это потенциальные ловушки могут вас застать.
Я действительно хочу ответить на этот вопрос, потому что первые 6 лет своей карьеры я программировал на VB до того, как появился .NET. Хотя я так давно не работал над VB6, что не могу припомнить ничего полезного. Я сочувствую вам и надеюсь, что вам не придется долго над этим работать.