turbo basic массивы

Милые люди, прошу Вас помочь мне в решении задач.
Задача:
В каждой строке марицы A(n,m) максимальный элемент поместить в конец строки, сохранив порядок остальных элементов.
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Turbo Basic- массивы
1. Удалите в целочисленном массиве все положительные числа, которые являются палиндромами.
turbo basic
Помогите пожалуйста, написать решение к задаче в turbo basic. Сама задача: Положение рта на лице.
В Turbo Basic
Даны пять различных целых чисел. Найти среди них два числа, модуль разности которых имеет.

Turbo Basic
ребялт, помогите, к курсачу нужна блок-схема.. во — 1 делал не сам, во — 2 не умею делать схемы(( .
Платежеспособный зверь
8917 / 4346 / 1641
Регистрация: 28.10.2009
Сообщений: 11,547
не знаю, сильно ли turbo отличается от qbasic, но в qbasic это решение выглядит так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
CLS INPUT "vvedite kol-vo strok ", n INPUT "vvedite kol-vo stolbcov ", m DIM a(n, m) FOR i = 1 TO n FOR j = 1 TO m INPUT "vvedite element ", a(i, j) NEXT NEXT PRINT "ishodnyj massiv" FOR i = 1 TO n FOR j = 1 TO m PRINT a(i, j); " "; NEXT PRINT NEXT FOR i = 1 TO n max = a(i, 1) nom = 1 FOR j = 1 TO m IF a(i, j) > max THEN max = a(i, j): nom = j NEXT FOR k = nom TO m - 1 a(i, k) = a(i, k + 1) NEXT a(i, m) = max NEXT PRINT "novyj massiv" FOR i = 1 TO n FOR j = 1 TO m PRINT a(i, j); " "; NEXT PRINT NEXT
Математические функции (Visual Basic)
Методы System.Math класса предоставляют тригонометрические, логарифмические и другие распространенные математические функции.
Замечания
В следующей System.Math таблице перечислены методы класса. Их можно использовать в программе Visual Basic:
| Метод .NET | Description |
|---|---|
| Abs | Возвращает абсолютное значение числа. |
| Acos | Возвращает угол, косинус которого равен указанному числу. |
| Asin | Возвращает угол, синус которого равен указанному числу. |
| Atan | Возвращает угол, тангенс которого равен указанному числу. |
| Atan2 | Возвращает угол, тангенс которого равен отношению двух указанных чисел. |
| BigMul | Возвращает полный продукт двух 32-разрядных чисел. |
| Ceiling | Возвращает наименьшее целочисленное значение, которое больше или равно указанному Decimal или Double равно. |
| Cos | Возвращает косинус указанного угла. |
| Cosh | Возвращает гиперболический косинус указанного угла. |
| DivRem | Возвращает кавычки двух 32-разрядных или 64-разрядных целых чисел со знаком, а также возвращает оставшуюся часть в выходном параметре. |
| Exp | Возвращает e (базу естественных логарифм), поднятую до указанной мощности. |
| Floor | Возвращает наибольшее целое число, которое меньше или равно указанному Decimal или Double числу. |
| IEEERemainder | Возвращает оставшуюся часть, которая приводит к делении указанного числа по другому указанному числу. |
| Log | Возвращает естественный (базовый e) логарифм указанного числа или логарифм указанного числа в указанной базе. |
| Log10 | Возвращает логарифм с основанием 10 указанного числа. |
| Max | Возвращает больше двух чисел. |
| Min | Возвращает меньшее из двух чисел. |
| Pow | Возвращает указанное число, возведенное в указанную степень. |
| Round | Decimal Возвращает или Double округляет значение, округленное до ближайшего целого значения или указанного числа дробных цифр. |
| Sign | Integer Возвращает значение, указывающее знак числа. |
| Sin | Возвращает синус указанного угла. |
| Sinh | Возвращает гиперболический синус указанного угла. |
| Sqrt | Возвращает квадратный корень из указанного числа. |
| Tan | Возвращает тангенс указанного угла. |
| Tanh | Возвращает гиперболический тангенс указанного угла. |
| Truncate | Вычисляет неотъемлемую часть указанного Decimal или Double числа. |
В следующей таблице перечислены методы System.Math класса, которые не существуют в платформа .NET Framework, но добавляются в .NET Standard или .NET Core:
| Метод .NET | Description | Доступно в |
|---|---|---|
| Acosh | Возвращает угол, гиперболический косинус которого равен указанному числу. | Начиная с .NET Core 2.1 и .NET Standard 2.1 |
| Asinh | Возвращает угол, гиперболический синус которого равен указанному числу. | Начиная с .NET Core 2.1 и .NET Standard 2.1 |
| Atanh | Возвращает угол, гиперболический тангенс которого равен указанному числу. | Начиная с .NET Core 2.1 и .NET Standard 2.1 |
| BitDecrement | Возвращает ближайшее самое маленькое значение, которое меньше, чем x . | Начиная с .NET Core 3.0 |
| BitIncrement | Возвращает ближайшее самое большое значение, превышающее x . | Начиная с .NET Core 3.0 |
| Cbrt | Возвращает кубический корень из указанного числа. | Начиная с .NET Core 2.1 и .NET Standard 2.1 |
| Clamp | Возвращает value , ограниченное диапазоном от min до max включительно. | Начиная с .NET Core 2.0 и .NET Standard 2.1 |
| CopySign | Возвращает значение с величиной x и знаком y . | Начиная с .NET Core 3.0 |
| FusedMultiplyAdd | Возвращает значение (x * y) + z, округленное в рамках одной тернарной операции. | Начиная с .NET Core 3.0 |
| ILogB | Возвращает целочисленный логарифм с основанием 2 указанного числа. | Начиная с .NET Core 3.0 |
| Log2 | Возвращает логарифм с основанием 2 указанного числа. | Начиная с .NET Core 3.0 |
| MaxMagnitude | Возвращает большую величину из двух чисел двойной точности с плавающей запятой. | Начиная с .NET Core 3.0 |
| MinMagnitude | Возвращает меньшую величину из двух чисел двойной точности с плавающей запятой. | Начиная с .NET Core 3.0 |
| ScaleB | Возвращает значение x * 2^n, вычисленное эффективно. | Начиная с .NET Core 3.0 |
Чтобы использовать эти функции без квалификации, импортируйте System.Math пространство имен в проект, добавив следующий код в начало исходного файла:
Imports System.Math
Пример : Abs
В этом примере метод Math класса используется Abs для вычисления абсолютного значения числа.
Dim x As Double = Math.Abs(50.3) Dim y As Double = Math.Abs(-50.3) Console.WriteLine(x) Console.WriteLine(y) ' This example produces the following output: ' 50.3 ' 50.3
Пример — Atan
В этом примере метод Math класса используется Atan для вычисления значения pi.
Public Function GetPi() As Double ' Calculate the value of pi. Return 4.0 * Math.Atan(1.0) End Function
Класс System.Math содержит Math.PI поле константы. Его можно использовать, а не вычислять.
Пример : Cos
В этом примере метод Math класса используется Cos для возврата косинуса угла.
Public Function Sec(angle As Double) As Double ' Calculate the secant of angle, in radians. Return 1.0 / Math.Cos(angle) End Function
Пример — Exp
В этом примере метод Math класса используется Exp для возврата e, поднятого в силу.
Public Function Sinh(angle As Double) As Double ' Calculate hyperbolic sine of an angle, in radians. Return (Math.Exp(angle) - Math.Exp(-angle)) / 2.0 End Function
Пример — журнал
В этом примере метод Math класса используется Log для возврата естественного логарифма числа.
Public Function Asinh(value As Double) As Double ' Calculate inverse hyperbolic sine, in radians. Return Math.Log(value + Math.Sqrt(value * value + 1.0)) End Function
Пример — округление
В этом примере метод Math класса используется Round для округления числа до ближайшего целого числа.
Dim myVar2 As Double = Math.Round(2.8) Console.WriteLine(myVar2) ' The code produces the following output: ' 3
Пример — знак
В этом примере метод Math класса используется Sign для определения знака числа.
Dim mySign1 As Integer = Math.Sign(12) Dim mySign2 As Integer = Math.Sign(-2.4) Dim mySign3 As Integer = Math.Sign(0) Console.WriteLine(mySign1) Console.WriteLine(mySign2) Console.WriteLine(mySign3) ' The code produces the following output: ' 1 ' -1 ' 0
Пример : Sin
В этом примере метод Math класса используется Sin для возврата синуса угла.
Public Function Csc(angle As Double) As Double ' Calculate cosecant of an angle, in radians. Return 1.0 / Math.Sin(angle) End Function
Пример : Sqrt
В этом примере метод Math класса используется Sqrt для вычисления квадратного корня числа.
Dim mySqrt1 As Double = Math.Sqrt(4) Dim mySqrt2 As Double = Math.Sqrt(23) Dim mySqrt3 As Double = Math.Sqrt(0) Dim mySqrt4 As Double = Math.Sqrt(-4) Console.WriteLine(mySqrt1) Console.WriteLine(mySqrt2) Console.WriteLine(mySqrt3) Console.WriteLine(mySqrt4) ' The code produces the following output: ' 2 ' 4.79583152331272 ' 0 ' NaN
Пример — Tan
В этом примере метод Math класса используется Tan для возврата тангенс угла.
Public Function Ctan(angle As Double) As Double ' Calculate cotangent of an angle, in radians. Return 1.0 / Math.Tan(angle) End Function
См. также
- Rnd
- Randomize
- NaN
- Производные математические функции
- Арифметические операторы
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Как я гонял Балду на Visual Basic for Applications для MS Access
Не помню, что меня так заело. Наверно, кто-нибудь обыграл меня в Балду с разгромным счетом (ее онлайн-вариант есть на Одноклассниках, Mail.ru и в куче других мест). Короче, я принял вызов. В прошлый раз так было с программкой для разгадки СУДОКУ. Но там все оказалось заметно проще.

Балда, она же Волшебный Квадрат. Игроки добавляют на каждом шагу по одной букве, чтобы получилось осмысленное слово как можно большей длины.
Будучи программистом старой закалки (FORTRAN, PL1 и стопка перфокарт), я считаю, что решительно все равно, на чем писать код. Из кардинальных идей, случившихся в истории программирования, стоит упомянуть только объектную ориентированность и реляционную модель данных (ну и еще, пожалуй, функциональное программирование, всякие лямбда-вещи, в противоположность привычному, процедурному подходу). Главное, все же, Алгоритм! Которые все в основном изложены в семитомнике «Основы программирования» Дональда Кнута. А какие команды отрисуют вам окно, иконку и прочие прелести – дело десятое. Семитомник Кнута, как и базовая статья по реляционным базам Эдгара Кодда из Исследовательского центра IBM, появились во второй половине 60-х годов. То есть почти полвека тому. Вот почему я пишу на VBA и не отвлекаюсь ни на какие новомодные вещи.
Вызовов (вот не люблю эту кальку с английского challenge, а привык!) при написании игры, собственно, было два. Правильно прописать рекурсивный алгоритм, а затем оптимизировать поиск слов в словаре.
С самим алгоритмом все достаточно просто. Вот есть игровое поле 5 на 5 с уже вписанными буквами. Нужно добавить еще одну букву, примыкающую к существующим с какой-либо стороны (кроме как по диагонали), и просмотреть в словаре все возникающие варианты слов при всех возможных вариантах «обхода» игрового поля, заполненного буквами. Тут и возникает рекурсия.
Начинаем по порядку с любой буквы и идем в любую сторону, где есть еще одна буква. Так набирается слово для проверки. Сами буквы, уже включенные в проверяемое слово, должны быть исключены из дальнейших проверок, так как слово не может быть с пересечениями (2 раза использовать одну и ту же букву нельзя).
Набранную строку символов на каждом этапе ищем в словаре. Если слово найдено – запоминаем этот вариант, но продолжаем поиск, не прерывая рекурсии, так как может существовать и более длинное слово с тем же началом (обнаружив КОТ, не упускаем шанса найти также КОТОВАСИЯ, КОТОВОДСТВО и т.д.)
Сигналом для выхода из рекурсии (это, как мы помним, самая важная часть в написании рекурсивных функций) будет попросту отсутствие возможности выбрать еще одну букву, когда все возможные на данном шагу ходы исчерпаны (уже включены в проверяемое слово или находятся в недосягаемости от того места игрового поля, где мы оказались на данном шаге). Тогда мы делаем выход, то есть отступаем на шаг назад и пытаемся двинуться в другую сторону. Полный выход из рекурсии произойдет, когда мы переберем все возможные варианты – все маршруты обхода поля с буквами.
При этом только что добавленная буква должна попасть в слово, которое мы проверяем. Но это правило нельзя включить априори – может статься, что эта буква окажется вообще последней, так что эту проверку нужно провести только в самом конце, перед поиском в словаре.
В этом месте меня удивило количество возникающих вариантов. В разгар игры (когда игровое поле уже заполнено, но и свободных клеток остается достаточно), система просматривает более 100 000 (прописью – ста тысяч) вариантов слов на каждом шагу! Мы явно имеем дело с задачей экспоненциальной сложности от размера поля (NP-полнота?). Поэтому от изначальной идеи – просчитать всякую игру на много ходов вперед, чтобы выбрать тот вариант, который не даст противнику длинных слов в его черед (при условии, конечно, что мы пользуемся одним и тем же словарем!) пришлось отказаться.
Кстати, глубина рекурсии совсем невелика – как понятно из описанного алгоритма, она не превышает количества букв на поле в данный момент.
В качестве словаря я взял словарь Зализняка (это тот самый ученый-лингвист, чьи таблицы по морфологии русского языка, по образованию словоформ, были положены в основу проверки синтаксиса в Microsoft Word 6.0 Игорем Агамирзяном). Согласно правилам Балды, можно использовать только существительные в именительном падеже единственном числе, таковых в использованном мной словаре было ровно 43 304, от «АБАЖУРА» до «ЯЩУРА».
Итак, мы имеем сто тысяч вариантов слов (в пике – до 150 000), которые надо поискать в словаре из 43 304 слов. Это выходит более шести миллиардов просмотров словаря, если я не ошибаюсь в подсчетах. Первая версия программы задумывалась над каждым ходом по несколько минут, и это безобразие нельзя было, конечно, терпеть. Не говоря уже о том, что если использовать программу для борьбы с реальным соперником, то на обдумывание хода дается не более минуты. А хочется еще заглянуть хотя бы на шаг вперед, чтобы не подставить противнику какое-нибудь супердлинное слово в его ход.
Итак, оптимизация. Во-первых, вся работа должна осуществляться только в оперативной памяти, объем данных это вполне позволяет. Весь словарь считывается из таблицы в массив, по которому затем и осуществляется поиск. Но этого явно недостаточно.
Вторым понятным способом оптимизировать является индексация. Её я сделал в 2-буквенном варианте. В отдельный массив, состоящий из всех возможных двухбуквенных пар, был внесен индекс, начиная с которого слова, начинающиеся на эти самые 2 буквы, расположены в массиве с полным словарем. Для того, чтобы не искать сначала в массиве индексов искомые 2 буквы, он был сделан полным, то есть содержал даже те пары букв, на которые в словаре нет ни одного слова. Таким образом, индекс в массиве индексов вычислялся напрямую из 2-х первых букв слова, которое мы ищем, то есть очень быстро.
Массив индексов также не занимает много места в памяти, его длина равна 32 x 32 = 1024 элемента. Реально, было несложно сделать индекс и 3-буквенным, но это, как показал опыт, не привело уже к дальнейшему ускорению.
Это еще не вся оптимизация! Я также расширил исходный словарь некоторым хэшем, если его можно так назвать – по сути, это было такое же слово, но в котором каждая буква встречалась только один раз (ПОТОП – ПТО). В результате самым быстрым вариантом поиска оказался такой:
— мы перебираем полный словарь, оставляя только те слова, которые содержат те же буквы, что и в слове, которое ищем;
— строим на этот урезанный словарь 2-буквенный индекс;
— ищем искомое слово, используя индекс.

Результат – поиск всех вариантов слов на каждом ходу занимает не более 2 секунд, при этом просматривается, как я уже говорил, до 150 000 слов в словаре и выдается до сотни вариантов хода — слов от 4-буквенных и выше. Можно также для каждого найденного варианта слова просчитать возможные будущие ходы противника – по цене 2 секунды за один вариант.
Теперь о MS Access. Я бесконечно влюблен в эту программу, так как она сочетает в себе вполне сносный реляционный движок базы данных, простое построение интерфейсов и мощный Visual Basic for Applications за сценой.
Последний, говорят, по скорости обработки строковой информации не уступает С++/ С# — что и было продемонстрировано оптимизацией нашей программы.
Что касается базы данных, то это, я считаю, единственно правильный формат хранения данных, на которых есть хоть какая-то структура. Это же позволяет писать программы «с накоплением» — то есть такие, расчет по которым занимает многие сутки (это всякие лингвистические задачи, которыми я порой балуюсь). Чтобы не потерять промежуточные результаты, их правильно скидывать в таблицы с некоторой регулярностью, которая не замедляет выполнение основных расчетов. Чтобы всегда была некоторая отправная точка, с которой можно было бы продолжить.

Интерфейс программы. Система предлагает все варианты ходов, отсортированные по убыванию длины. При желании, можно просмотреть вперед возможный следующий ход противника при выборе нами того или иного варианта слова.
А вот так выглядит матч с противником. Нужно аккуратно вносить его ходы, и программа подскажет самый лучший вариант.
Хотите меня поругать за нечестность? Но программу я написал и оптимизировал сам! Причем, играл на интерес, а не ради каких-нибудь благ. Более того, почти все соперники используют что-то подобное, но написанное не ими самими – это видно сразу. Откуда у 15-летнего парня, чей профиль полон фоток с котиками, знание слова ПРОЗЕЛИТИЗМ? («Что делает малютка Тиффани в неблагоприятном районе в час ночи с учебником квантовой физики в руках?»)
- MS Office
- MS Access
- VBA
- visual basic for applications
- офисное программирование
- Программирование
- Visual Studio
- Microsoft Access
- Visual Basic for Applications
Советы тем, кто программирует на VB & VBA
Для обмена данными между двумя строковыми переменными можно использовать такую простую процедуру:
Sub SwapString (String1$, String2$) Dim Save$ Save = String1$ ' запись в промежуточную переменную String1$ = String2$ String2$ = Save$ End If
Однако мы уже неоднократно подчеркивали, что операции присвоения строковых переменных требуют довольно много времени, так как это связано с динамическим перерезервированием оперативной памяти. Кроме того, время их выполнения напрямую зависит от длины строк.
Мы предлагаем «хитрый» вариант взаимного обмена содержимого двух строк, который выполняется очень быстро и не зависит от числа байтов в строке. Он основан на использовании API-функции для копирования областей памяти и применении реально существующих, но не описанных в документации функций VB (так называемые недокументированные функции):
Declare Sub CopyMemory Lib "kernel32" Alias _ "RtlMoveMemory" (Destination As Any, _ Source As Any, ByVal Length As Long) Public Sub SwapSrting(String1$, String2$) Dim Save As Long 'Своппинг двух строковых переменных Save = StrPtr(String1) Call CopyMemory(ByVal VarPtr(String1), ByVal VarPtr(String2), 4) Call CopyMemory(ByVal VarPtr(String2), Save, 4) End Sub
Как известно, в VB строковые переменные имеют описатель (дескриптор) и собственно содержимое строки. В данном случае мы выполняем своппирование не содержимого строк, а содержимого описателей. Для этого используются две недокументированные VB-функции:
StrPrt — возвращает четырехбайтовый адрес содержимого строки;
VarPrt — возвращает четырехбайтовый адрес дескриптора.
Здесь нужно отметить два момента:
- Такой прием можно использовать только для своппинга — операцию присвоения строковой переменной таким образом делать нельзя (недопустимо, чтобы одна и та же строка данных использовалась в двух разных дескрипторах).
- В VB описатель строки содержит только адрес ее содержимого. Число байтов строки находится в четырех байтах, которые хранятся непосредственно перед этим содержимым, то есть функция LenB(MyString$) может быть реализована в виде такой конструкции:
Dim LenBmy& Call CopyMemory(LenBmy$, ByVal StrPtr(MyString$) - 4, 4)
Тем, кто еще пользуется QuickBasic для DOS, напомним, что здесь длина строки хранится в ее описателе вместе с адресом. Но нужно иметь в виду, что адресация строк в QB 4.x и PDS 7.x различается, и соответственно различаются описатели строк. Адрес дескриптора можно получить командами VARSEG (адрес сегмента) и VARPRT (смещение внутри сегмента); копирование областей памяти производится командами PEEK (чтение байта) и POKE (запись байта).
Совет 299. Динамическое управление меню
Многие программисты порой забывают о том, что меню, создаваемое с помощью Menu Editor, состоит из компонентов, которые работают так же, как и все остальные элементы управления. Это, в частности, позволяет непосредственно в процессе работы приложения управлять пользовательским интерфейсом. Так, можно изменять название команды меню (свойство Caption), делать ее недоступной для выполнения (Enable) или невидимой (Visible). Если же вы создали массив меню, назначив данному компоненту индекс (свойство Index), динамически создавать или удалять элементы такого массива, можно, например, следующим образом:
i% = mnuFileArray.Ubound + 1 ' следующий номер индекса после самого большого уже существующего Load mnuFileArray(i%) ' создание нового элемента массива меню mnuFileArray(i%).Caption = "NewArray" & i% ' название команды . Unload mnuFileArray(1) ' удалить элемент с индексом 1
Совет 300. Используйте каталог Template
Если у вас есть VB-проект, который вы хотите хотя бы иногда использовать в качестве шаблона при создании новых проектов, поместите его в каталог . \VisualStudio\VB98\Template\Projects\ или другой каталог, который вы указали при установке VB 6.0. (Для VB 5.0 этот каталог называется VB5\Template\Projects\.)
Тогда ваш шаблон будет автоматически появляться в окне New Project при создании нового проекта.
Такой вариант создания нового проекта на основе шаблона лучше, чем простая загрузка существующего проекта командой Open, ибо в последнем случае есть опасность забыть, что необходимо обязательно сразу же сохранить проект и все его компоненты командой Save As, иначе все изменения проекта будут записываться в исходный шаблон.
Точно так же вы можете записать шаблоны для отдельных компонентов проекта, которые хранятся в подкаталоге Template:
Совет 301. Используйте Microsoft Forms 2.0 Form (когда это нужно)
Если вы хотите создавать программные компоненты формы (модули формы), которые можно использовать как в VB, так и в Office/VBA, то вам нужно пользоваться конструктором MS Forms 2.0. В среде VBA он вызывается командой Insert|UserForm, в среде VB — Project|Add Microsoft Forms 2.0 Form (если такая команда отсутствует в среде VB, то конструктор нужно подключить с помощью команды Project|Components|Designers).
Напомним, что формы UserForms в VBA – это не то же самое, что VB-формы (Ruby Forms). VBA UserForms являются экземплярами ActiveX-конструктора Microsoft Forms 2.0 (FM20.dll), который входит в состав как VB, так и VBA. Более того, все элементы управления, представленные в нем по умолчанию, являются не встроенными, а ActiveX-компонентами (то есть при желании их можно подключить и к VB-форме). Чтобы убедиться в этом, откройте окно Tools|Additional Controls.
К сожалению, эти два вида форм различаются не только форматом их модулей. Каждая из них использует свой собственный набор встроенных элементов управления. Проблема же заключается в том, что эти наборы не только не совпадают функционально, но даже для одинаковых по значению элементов управления используются разные наименования свойств, событий и методов. MS Forms 2.0 не поддерживают ряд очень полезных встроенных элементов управления VB (Timer, FileListBox, PictureBox, DriveListBox, DirListBox, Menu, Shape и Line), но при этом включают другие полезные компоненты (TabStrip, MultiPage) и команды проектирования формы (TabOrder).
Совет 302. Используйте элемент управления IE Timer
Отсутствие встроенных элементов управления (на что мы сетовали в предыдущем совете) можно компенсировать возможностью использования дополнительных элементов управления ActiveX. Если у вас имеется VB 5.0 или 6.0, то вы можете самостоятельно сделать, например, на основе встроенного элемента Timer собственный ActiveX-компонент для реализации функции таймера. Такой OCX можно было бы использовать в конструкторе MS Forms 2.0 (VBA-формы). Но прежде чем делать свои компоненты, стоит посмотреть, нет ли уже готового подходящего элемента на Web-сайтах с VB-ресурсами и разными Freeware & Shareware.
Так, очень нужный порой компонент Timer в виде файла IETimer.OCX можно найти по адресу www.visual.2000.ru/develop/vb/source/.
Но здесь мы хотели бы отметить некоторые различия в процедурах подключения OCX к среде VB и VBA.
- Обычно OCX-компоненты помещаются в системный каталог Windows/System/. Однако мы рекомендуем размещать такие дополнительные файлы в каком-нибудь специально созданном для этого пользовательском подкаталоге. Это упростит процедуры «чистки мусора» и обновления версий компонентов, так как можно будет четко следить за тем, что вы записали сами, а что автоматически прописали в System операционная система и программы установок разных приложений.
- Далее необходимо зарегистрировать OCX-файл. Лучше всего это сделать с помощью утилиты RegSvr32.exe, которая входит в состав VB и Office (проще всего скопировать ее в подкаталог с вашими OCX): RegSvr32.exe Your.OCX
- Подключение к панели Toolbox для VB- и VBA-форм несколько различается.
- для VB-форм (в среде VB) выберите команду Project|Components, а потом во вкладке Controls установите флажок IE Timer (в данном случае зарегистрировать OCX можно, подключив нужный файл с помощью кнопки Browse);
- в среде Office/VBA также имеется команда (и диалоговое окно) Insert|Components|Controls, но зачем она здесь присутствует, куда подключаются выделенные элементы управления, — этого мы не поняли.
Для подключения дополнительного элемента управления в среде VBA выберите команду Tools|Additional Controls. К ней можно также обратиться с помощью контекстного меню, которое появляется после щелчка правой кнопкой мыши панели Toolbox (только так и можно сделать, работая с MS Forms 2.0 в среде VB). Но проблема в данном случае заключается в том, что имя искомого компонента будет другим — Timer Object.
Но иногда оказывается, что этого недостаточно, и приходится вручную просматривать (искать заданный файл) и чистить Реестр.
Совет 303. Как погрузить приложение в «глубокий сон»
Мы уже приводили несколько советов, как можно приостановить выполнение приложения на некоторое время. В частности, это можно сделать с помощью элемента управления Timer или путем опроса текущего времени (обращения к функции Timer) в цикле программы. Однако оба варианта имеют некоторые ограничения. Например, элемент управления Timer позволяет делать задержку в диапазоне от 1 секунды до 1 минуты, а функция Timer имеет минимальную дискретность в 1 секунду. При использовании соответствующей API-функции этих ограничений нет:
' описание функции Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) ' обращение к ней (аргумент задается в миллисекундах) Sleep 150010 ' ожидание 150,01 секунды
Но при использовании этой конструкции есть другая проблема — «глубокий сон» приложения не удастся прервать до истечения заданного интервала времени.
Совет 304. Управление расстоянием между столбцами в ListBox
С помощью API-функции SendMessage вы можете управлять позициями табулятора в элементе управления ListBox. Это может быть полезно, если каждая строка списка состоит из полей, разделенных символом Tab (код ASCII = 9), то есть если список выводится в виде таблицы, содержащей несколько колонок. Для этого в программный модуль запишите такое объявление и подпрограмму:
Private Declare Function SendMessage Lib _ "user32" Alias "SendMessageA" _ (ByVal hWnd As Long, ByVal wMsg As Long, _ ByVal wParam As Long, lParam As Any) As Long Private Const LB_SETTABSTOPS = &H192 Public Sub SetListTabStops(MyListBox As ListBox, _ ParamArray ParmList() As Variant) 'Коррекция позиции Tabs в списке ListBox ' ' Для передачи переменного числа однородных параметров ' используется конструкция ParamArray ' ВНИМАНИЕ! Нижний индекс ParmList равен 0 ' даже при Option Base 1. ' Позиция табулятора определяется в специальных величинах ' окна, которая в среднем равна 1/4 символа Dim i As Long Dim NumColumns As Long ' ' формирование массива для установки табуляторов ReDim ListTabs(0 To UBound(ParmList)) As Long For i = 0 To UBound(ParmList) ListTabs(i) = ParmList(i) Next i NumColumns = UBound(ParmList) + 1 ' ' установка новых значений позиций табулятора Call SendMessage(MyListBox.hWnd, LB_SETTABSTOPS, _ NumColumns, ListTabs(0)) ' вывести новое изображение списка lstMyListBox.Refresh End Sub
Чтобы протестировать эту конструкцию, создайте форму, на которой разместите элемент списка lstMyListBox и две командные кнопки Command1 и Command2. Далее запишите такой программный код для этих компонентов:
Private Sub Form_Load() ' Начальное формирование списка ' с тремя колонками, разделенными символом vbTab = Chr$(9) lstMyListBox.AddItem "Колонка11" & vbTab & "Колонка12" _ & vbTab & "Колонка13" lstMyListBox.AddItem "C21" & vbTab & "C22" _ & vbTab & "C23" End Sub Private Sub Command1_Click() ' одинаковое расстояние в 52 позиции (13 символов) Call SetListTabStops(lstMyListBox, 52) End Sub Private Sub Command2_Click() ' переменное расстояние (10 и 30 символов) Call SetListTabStops(lstMyListBox, 40, 120) End Sub
Запустите на выполнение созданный проект, и вы увидите такое изображение списка (рис. 2)
Щелкните кнопку Command1 — список примет следующий вид (рис. 3)
Щелкните Command2, и получится другое изображение (рис. 4)
Совет 305. Где хранятся настройки панелей инструментов MS Office
Как известно, пользователь MS Office 97/2000 может выполнять различные операции по настройке меню и панелей инструментов среды — модифицировать, удалять и добавлять команды и панели. Это можно делать как с помощью команды Настройка (Customize), так и программным образом (VBA). Но где хранятся эти настройки, как они связаны с обрабатываемыми документами? Это полезно знать, особенно если вы хотите перенести эти настройки на другой компьютер. Тем более что реализация механизма сохранения настроек для всех офисных приложений различная (это к вопросу о том, что MS Office представляет собой как бы единое семейство продуктов).
Word
Это приложение обладает наиболее удобной и гибкой системой настроек. Как известно, VBA-проекты хранятся в документах или шаблонах Word. В них же хранятся и настройки панелей инструментов, и пользователь может сам выбирать, в каком именно файле они будут записаны.
Таким образом можно реализовать самые разнообразные варианты подключения расширений пользовательской среды. Если записать эти настройки в глобальный шаблон (например, в Normal.dot), то данные команды будут доступны при работе со всеми документами в данной сессии. При сохранении установок в конкретный документ они будут применяться только в нем. Если же настройки включены в присоединенный шаблон, они будут появляться во всех документах, которые его используют.
Excel и PowerPoint
В этих двух приложениях макрокод хранится в документах (рабочих книгах и презентациях), а сами настройки панелей инструментов — в фиксированных файлах. Для версии 97 это соответственно файлы .xlb и .pcb в каталоге Windows, для версии 2000 — файлы Excel\Excel.xlb и PowerPoint\ppt.pcb, которые находятся в каталоге Windows\Application Data\Microsoft\. Таким образом, получается, что пользователь может работать только с одним фиксированным вариантом настроек панелей инструментов.
Но в этих приложения механизм работы команд несколько различается. Для примера напишите такую макрокоманду:
Sub Hello MsgBox "Hello!" End Sub
которую запишите в книгу Hello.xls и презентацию Hello.ppt. Соответственно в Excel и PowerPoint сделайте кнопку на панели инструментов для обращения к этим макрокомандам. Затем перезагрузите Excel: на панели инструментов будет видна ваша кнопка, хотя программный код для нее не загружен. Нажмите кнопку — произойдет загрузка Hello.xls и выполнится макрокоманда. Теперь повторите те же действия для PowerPoint — макрокоманда выполнится, но презентация не загрузится в среду приложения.
В Excel можно скопировать созданные пользователем панели инструментов в рабочую книгу (со встроенными это проделать нельзя!). Это делается с помощью диалогового окна Attach Toolbars (вызывается командой Attach на вкладке ToolBars окна Customize) — программным образом с применением VBA это сделать нельзя.
После копирования можно удалить пользовательские панели из среды самого Excel с помощью команды Delete окна Customize или метода Delete коллекции CommandBars. Удалить панель из рабочей книги можно только с помощью диалогового окна.
Важное замечание. Когда вы открываете рабочую книгу, производится автоматическое копирование пользовательских панелей из книги в среду Excel (но только в том случае, если панелей с такими именами не было в самом приложении!). При этом следует иметь в виду, что при закрытии рабочей книги эти панели остаются в Excel. Поэтому, если вы хотите, чтобы подобные компоненты появлялись только в сеансе работы с данной рабочей книгой, вы можете программным образом сделать удаление панели при закрытии книги. Если же вы не удалите пользовательскую панель из Excel и будете корректировать ее, то в последующих сеансах вы будете работать именно с ней (копирование из рабочей книги не будет выполняться).
Outlook и FrontPage
В этих двух приложениях все сделано еще проще: программный код хранится в строго фиксированных проектах — Outlook\VbaProject.OTM и FrontPage\Macros\Microsoft FrontPage.fpm, а настройки среды — в столь же фиксированных Outlook\outcmd.dat и FrontPage\State\cmpUI.prt. Все это, в свою очередь, находится в подкаталоге Windows\Application Data\Microsoft\.
Примечание. Для приложений Excel, PowerPoint, Outlook и FrontPage каталог Windows\Application Data\Microsoft\ используется только в случае однопользовательского режима. Если же в операционной системе установлен многопользовательский режим с использованием различных профилей, то в этом случае используется каталог Windows\Profiles\Username\Application Data\Microsoft\.
Access
В документах Microsoft пользовательские настройки встроенных панелей инструментов среды Access хранятся в «специальной базе данных». Наши исследования показали, что эта база — Реестр Windows, хранящийся по адресу: HKCU\Software\Microsoft\Office\9.0\Access\Settings\Commandbars\. Но что и как туда пишется — нам разобраться не удалось. Панели же инструментов, создаваемые с помощью Access, хранятся в файлах этой базы данных.
Совет 306. Управление порядком перемещения по элементам управления
Как известно, перемещение фокуса от одного элемента управления к другому можно выполнять с помощью клавиатуры: Tab (вперед) или Shift+Tab (назад). Порядок передвижения определяется значением свойства TabIndex элементов управления, который начинается с нуля и для каждого размещаемого на форме элемента управления увеличивается на единицу. Свойство TabIndex, конечно же, имеется только у видимых компонентов (у Timer его нет). Пассивные визуальные компоненты типа Label имеют свойство TabIndex, но фактически не используют его — при перемещении по форме такие элементы автоматически пропускаются.
Для изменения последовательности обхода визуальных компонентов (она редко совпадает с тем порядком, в котором мы создавали диалоговый интерфейс) нужно менять свойства TabIndex. Это можно делать вручную, напрямую корректируя параметры в окне Properties. Обратите внимание, что ошибка использования одного и того же значения TabOrder для разных компонентов здесь исключена за счет автоматической перенумерации.
Пусть, например, у вас имеются четыре компонента с номерами 0, 1, 2, 3. Для последнего вы решили установить TabOrder=1. В этом случае автоматически изменятся значения свойств TabOrder для двух элементов управления: 1->2, 2->3.
Однако гораздо удобнее использовать специальные визуальные средства управления перемещения по элементам формы. Как мы отмечали в совете 301, конструктор MS Forms 2.0 (в среде VB и VBA) для этого использует специальную встроенную команду TabOrder. Чтобы воспользоваться ею, щелкните правой кнопкой мыши форму и в появившемся контекстом меню выберите команду Tab Order. В появившемся одноименном диалоговом окне выделите нужные компоненты и с помощью кнопок Move Up и Move Down передвиньте их в нужную позицию списка, который определяет порядок перемещения (рис. 306-1).
Для обычных VB-форм такой встроенной команды нет, и по этому поводу мы уже выказывали свое недовольство в адрес разработчиков из Microsoft. Однако мы были не правы — такие визуальные средства имеются в VB 5 и VB 6 в виде автономного дополнения TabOrder (исходный код этого проекта находится в подкаталоге . \MSDN98\98VS\1033\Samples\VB98\TabOrder\ для VB6 или в . \Samples\CompTool\AddIns\TabOrder\).
Чтобы сделать Add-In (на примере VB 6.0), загрузите проект TabOrder.VBP и
выполните команду File|Make TabOrder.DLL. В результате вы не только создадите исполняемый модуль, но и зарегистрируете новое дополнение, которое появится под названием Tab Order Sample Addin в окне Add-Ins|Add-In Manager среды Visual Basic. Для работы с TabOrder необходимо обычным образом установить режим загрузки в этом окне, и тогда на панели инструментов VB появится кнопка TabOrder Window для запуска этого дополнения (рис. 306-2).
Примечание. При работе в VB 5 для включения TabOrder (созданного в этой же среде!) в окно Add-In Manager необходимо добавить в секцию [Add-Ins32] файла VBADDIN.INI строку TabOrder.Connect=0.
Теперь создайте в VB какой-нибудь тестовый пример с формой, на которой разместите несколько разных элементов управления, и щелкните кнопку TabOrder Window. В появившемся окне (рис. 306-3) можно корректировать последовательность перемещения по элементам управления формы. Однако здесь имеются дополнительные функции, которых нет в аналогичной утилите MS Forms 2.0. Обратите внимание, что на нашей тестовой форме все элементы управления расположены на разных расстояниях от верхней и правой границ формы. С помощью соответствующих кнопок на панели инструментов можно упорядочить список по вертикальному (рис. 306-4) или горизонтальному (рис. 306-5) расположению визуальных компонентов. Кроме того, программист без перезагрузки этой утилиты может восстановить исходную последовательность списка.
Вообще, мы рекомендуем внимательно изучить проект TabOrder, так как он представляет собой интересный пример создания Add-In, использования User-документов и ресурсных файлов.
Но один вопрос все же остается — зачем нужно было делать для VB-форм и MS Forms 2.0 две похожие, но тем не менее разные утилиты?
Совет 307. Как удалить каталог
VB содержит довольно много встроенных функций и операторов для управления файлами и каталогов. Совершенно очевидно, что эти средства работают через Win API, и понятно, что последние обладают более широкими возможностями. Чаще всего встроенные функции VB реализуют усеченный вариант соответствующей API-функции (например, оператор MkDir представляет собой частный случай функции CreatDirectory). Многие же возможности API вообще не представлены в виде VB-операторов. В частности, это относится к операции удаления каталогов, которая может быть выполнена таким образом:
Private Declare Function RemoveDirectory& Lib "kernel32" Alias _ "RemoveDirectoryA" (ByVal lpPathName As String) ' Удаление каталога (пустого!) PathName$ = "D:\t\" ' в конце имени "\" необязательна ' code& = RemoveDirectory(PathName) If code& = 0 Then ' операция удаления не была выполнена Else ' каталог удален End If
Здесь нужно обратить внимание на несколько моментов:
- Удаляемый каталог должен быть пустым.
- Имя каталога не обязательно должно заканчиваться на «\» — операция будет успешно выполнена с именем «D:\t».
- Почему-то при наличии ошибки обращение к функции GetLastError выдает исключительно 0 (то есть нельзя уточнить характер ошибки).
Совет 308. Как удалить непустой каталог
Но как удалить каталог, если в нем находятся файлы и вложенные подкаталоги? Для этого потребуется написать процедуру DeleteDir, которая будет перед удалением каталога просматривать и удалять его содержимое. Обращение к ней может выглядеть следующим образом:
Dim DirCount%, FileCount% ' число удаленных каталогов и файлов ' DirName$ = "d:\t\" ' DirCount = 0: FileCount = 0 ' начальная установка Result& = DeleteDir&(DirName$, DirCount%, FileCount%) ' Result = 0 - удален
А сама процедура будет содержать такой код:
Public Function DeleteDir&(DirName$, DirCount%, FileCount%) ' ' Удаление каталога со всем его внутренним содержанием ' ВХОД: ' DirName$ -- имя удаляемого каталога ' ВЫХОД: ' DeleteDir - код завершения (0 - удален, <>0 - не удален ' DirCount, FileCount -- текущее число удаленных каталогов и файлов ' (перед первым обращении эти переменные должны быть обнулены) ' Dim Result& ' ' 1. Удалить все внутри каталога Call DeleteDirAll(DirName$, DirCount%, FileCount%, Result&) If Result = 0 Then ' без ошибок ' 2. удалить сам каталог Result = RemoveDirectory(DirName$) If Result = 0 Then Result = -1 Else: Result = 0: DirCount = DirCount + 1 End If End If DeleteDir = Result ' код завершения End Function
Но очевидно, что ключевой задачей здесь является написание процедуры DeleteDirAll, которая будет удалять внутреннее содержание каталога — файлы и подкаталоги. Тут не обойтись без использования рекурсии, и поэтому полезно вспомнить наши советы 229-231. Более того, нам понадобится готовый код подпрограммы CurrentDirCounter («как есть»), а также продпрограмма FileNameCase, которую можно использовать в качестве заготовки и создать DeleteDirAll:
Public Sub DeleteDirAll(DirName$, DirCount%, FileCount%, Result&) ' ' Удаление всех файлов и подкаталогов заданного каталога ' ReDim arrFile$(100) ' для имен элементов оглавления Dim CountFile%, NewPathName$, i% ' On Error GoTo ErrorDeleteFile ' формируем список файлов каталога Call CurrentDirCounter(DirName$, "*.*", CountFile%, arrFile$(), 0) ' удаление файлов If CountFile > 0 Then ' есть файлы в подкаталоге For i = 1 To CountFile Kill DirName$ & arrFile$(i) ' удалить файл FileCount = FileCount + 1 ' счетчик удаленных файлов Next End If 'формирование списка подкаталогов Call CurrentDirCounter(DirName$, "", CountFile%, arrFile$(), vbDirectory) If CountFile > 0 Then ' есть подкаталоги For i = 1 To CountFile ' формирование имени вложенного подкаталога NewPathName$ = DirName$ + arrFile$(i) + "\" '!! рекурсивное обращение к функции удаления каталога ' с новым именем, но старыми значениями счетчиков Result = DeleteDir&(NewPathName$, DirCount%, FileCount%) If Result <> 0 Then Exit Sub ' была ошибка Next End If Exit Sub ErrorDeleteFile: Result = Err ' ошибка при удалении файла End Sub
- ПК и комплектующие
- Настольные ПК и моноблоки
- Портативные ПК
- Серверы
- Материнские платы
- Корпуса
- Блоки питания
- Оперативная память
- Процессоры
- Графические адаптеры
- Жесткие диски и SSD
- Оптические приводы и носители
- Звуковые карты
- ТВ-тюнеры
- Контроллеры
- Системы охлаждения ПК
- Моддинг
- Аксессуары для ноутбуков
- Принтеры, сканеры, МФУ
- Мониторы и проекторы
- Устройства ввода
- Внешние накопители
- Акустические системы, гарнитуры, наушники
- ИБП
- Веб-камеры
- KVM-оборудование
- Сетевые медиаплееры
- HTPC и мини-компьютеры
- ТВ и системы домашнего кинотеатра
- Технология DLNA
- Средства управления домашней техникой
- Планшеты
- Смартфоны
- Портативные накопители
- Электронные ридеры
- Портативные медиаплееры
- GPS-навигаторы и трекеры
- Носимые гаджеты
- Автомобильные информационно-развлекательные системы
- Зарядные устройства
- Аксессуары для мобильных устройств
- Цифровые фотоаппараты и оптика
- Видеокамеры
- Фотоаксессуары
- Обработка фотографий
- Монтаж видео
- Операционные системы
- Средства разработки
- Офисные программы
- Средства тестирования, мониторинга и диагностики
- Полезные утилиты
- Графические редакторы
- Средства 3D-моделирования
- Веб-браузеры
- Поисковые системы
- Социальные сети
- «Облачные» сервисы
- Сервисы для обмена сообщениями и конференц-связи
- Разработка веб-сайтов
- Мобильный интернет
- Полезные инструменты
- Средства защиты от вредоносного ПО
- Средства управления доступом
- Защита данных
- Проводные сети
- Беспроводные сети
- Сетевая инфраструктура
- Сотовая связь
- IP-телефония
- NAS-накопители
- Средства управления сетями
- Средства удаленного доступа
- Системная интеграция
- Проекты в области образования
- Электронный документооборот
- «Облачные» сервисы для бизнеса
- Технологии виртуализации
1999 1 2 3 4 5 6 7 8 9 10 11 12 2000 1 2 3 4 5 6 7 8 9 10 11 12 2001 1 2 3 4 5 6 7 8 9 10 11 12 2002 1 2 3 4 5 6 7 8 9 10 11 12 2003 1 2 3 4 5 6 7 8 9 10 11 12 2004 1 2 3 4 5 6 7 8 9 10 11 12 2005 1 2 3 4 5 6 7 8 9 10 11 12 2006 1 2 3 4 5 6 7 8 9 10 11 12 2007 1 2 3 4 5 6 7 8 9 10 11 12 2008 1 2 3 4 5 6 7 8 9 10 11 12 2009 1 2 3 4 5 6 7 8 9 10 11 12 2010 1 2 3 4 5 6 7 8 9 10 11 12 2011 1 2 3 4 5 6 7 8 9 10 11 12 2012 1 2 3 4 5 6 7 8 9 10 11 12 2013 1 2 3 4 5 6 7 8 9 10 11 12