Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

MB60UG

.pdf
Скачиваний:
12
Добавлен:
13.02.2015
Размер:
1.47 Mб
Скачать

Глава 4: Основы языка MapBasic

которые должны были бы по смыслу Вашей задачи быть одинаковыми, будут восприняты как различные.

Чтобы получить вариант строки без завершающих дополнительных пробелов, используйте функцию RTrim$( ). Затем ее можно сравнить с результатом применения функции

RTrim$( ) к строке произвольной длины, не беспокоясь о влиянии дополняющих пробелов.

Логические операторы: Логические операторы применяются к логическим значениям и возвращают TRUE или FALSE:

Оператор

TRUE, åñëè

Пример

And

оба операнда истинны

If a And b Then...

Or

значение одного из

If a Or b Then...

 

операндов – истина

 

Not

операнд ложен

If Not a Then...

Например, следующий оператор If...Then выполняет две проверки: меньше ли значение переменной x, чем ноль, и больше ли значение x, чем 10. Если проверка не проходит, программа выдает сообщение об ошибке.

If x < 0 or x > 10 Then

Note "Число вне допустимого диапазона."

End If

Географические операторы: Эти операторы применяются к выражениям типа Object и выдают логический результат TRUE или FALSE.

Оператор

Возвращает TRUE, если

Пример

 

 

 

Contains

первый объект содержит

If a Contains b Then...

 

центроид второго объекта

 

 

 

 

Contains Part

первый объект содержит часть

If a Contains Part b Then...

 

второго объекта

 

 

 

 

Contains Entire

первый объект полностью

If a Contains Entire b Then...

 

содержит второй объект

 

 

 

 

Within

центроид первого объекта

If a Within b Then...

 

содержит второй объект

 

 

 

 

Partly Within

второй объект содержит часть

If a Partly Within b Then...

 

первого объекта

 

 

 

 

Entirely Within

второй объект полностью

If a Entirely Within b Then...

 

содержит первый объект

 

 

 

 

Intersects

два объекта имеют общую точку

If a Intersects b Then...

 

 

 

Более подробные сведения о графических объектах содержатся в главе 9.

45

Глава 4: Основы языка MapBasic

Порядок применения операторов в языке MapBasic

Некоторые операторы имеют более высокий приоритет, чем другие. Это означает, что при вычислении сложных выражений MapBasic следует определенному порядку применения операторов. Чтобы понять, как MapBasic обрабатывает сложные выражения, Вы должны знать относительные приоритеты операторов языка MapBasic.

Рассмотрим следующий оператор присваивания:

x = 2 + 3 * 4

В правой части используется две операции – сложение и умножение. Понятно, что результат вычисления зависит от последовательности применения операторов. Если сначала выполнить сложение (сложим 2 + 3 и получим 5), а затем умножение (5 * 4), то итоговым результатом будет 20. В действительности, однако, умножение имеет более высокий приоритет, чем сложение. Это означает, что MapBasic сначала выполнит умножение (3 * 4, получим 12), а затем уже сложение (2 + 12, получим 14).

Чтобы изменить стандартный порядок применения операторов языка MapBasic, надо использовать группировку с помощью скобок. Например, чтобы в приведенном примере сначала выполнялось сложение, его нужно переписать следующим образом:

x = (2 + 3) * 4

В данной таблице приведены приоритеты операторов языка MapBasic.

Высший приоритет: скобки

возведение в степень

отрицание

умножение, деление, Mod, целочисленное деление

сложение, вычитание, склеивание строк &

географические операторы, операторы сравнения, Like

Not

And

Низший приоритет: Or

Операторы, перечисленные в одной строке, имеют одинаковый приоритет. Операторы с более высоким приоритетом выполняются ранее других. Операторы с одинаковым приоритетом выполняются в выражении слева направо, исключая операторы возведения в степень, которые выполняются справа налево.

46

Глава 4: Основы языка MapBasic

Циклы и другие управляющие операторы

Управляющие операторы определяют порядок выполнения других операторов. В языке

MapBasic имеется три типа управляющих операторов:

Условные операторы позволяют пропускать выполнение некоторых операторов в программе на языке MapBasic (например, If...Then, GoTo).

Операторы цикла позволяют повторять группу операторов несколько раз (например, For...Next, Do...While).

Другие специальные управляющие операторы (End Program è äð.).

Оператор If...Then

Оператор If...Then языка MapBasic очень похож на условные операторы If...Then в других языках программирования. В операторе If...Then проверяется истинность условия; если оно истинно, MapBasic выполняет операторы, расположенные после ключевого слова

Then. В следующем примере MapBasic выдает сообщение об ошибке и вызывает процедуру reset_counter, если значение счетчика слишком мало:

If counter < 0 Then

Note "Ошибка: Счетчик слишком мал."

Call reset_counter

End If

В операторе If...Then может также присутствовать предложение Else. Если условие ложно, то MapBasic выполняет операторы, расположенные после ключевого слова Else, вместо того, чтобы выполнять операторы, расположенные после ключевого слова Then. Вот пример использования предложения Else.

If counter < 0 Then

Note "Ошибка: Счетчик слишком мал."

Call reset_counter

Else

Note "Счетчик в порядке."

End If

В операторе If...Then можно также использовать одно или несколько предложений ElseIf. Предложение ElseIf предназначено для проверки дополнительных условий. Если в условном операторе присутствует предложение ElseIf и проверявшееся условие ложно, то MapBasic проверит условие из предложения ElseIf, например:

If counter < 0 Then

Note "Ошибка: Счетчик слишком мал." Call reset_counter

ElseIf counter > 100 Then counter = 100

Note "Ошибка: Значение счетчика (100) слишком велико." Else

Note "Счетчик в порядке." End If

Отметим, что ключевое слово ElseIf пишется слитно. Оператор If...Then может содержать несколько предложений ElseIf, указанные в них условия проверяются последовательно. Впрочем, если Вам нужно проверить несколько условий, Вы можете использовать оператор

47

Глава 4: Основы языка MapBasic

Do...Case (см. описание ниже) вместо оператора If...Then со множеством предложений

ElseIf.

Оператор Do Case

Оператор Do Case выполняет набор проверок, чтобы установить, какому из предусмотренных значений равно текущее значение выражения. Для каждого из предусмотренных значений выполняется своя последовательность операторов.

В следующем примере проверяется, к какому кварталу относится текущий месяц. Если текущий месяц относится к первому кварталу (Январь-Февраль-Март), то текстовой переменной присваивается константа “Первый квартал года". Аналогично, если текущий месяц относится ко второму кварталу, то текстовой переменной присваивается константа “Второй квартал года“ и т.д.

Dim current_month, quarter As SmallInt, report_title As String

current_month = Month( CurDate() )

'

'В данный момент значение переменной current_month равно 1,

'если текущим месяцем является январь, 2 – февраль и т.д.

Do Case current_month Case 1, 2, 3

'Если текущий месяц – 1 (янв), 2 (фев) или 3 (март),

'Сейчас первый квартал.

'Присвоить соответствующее значение.

'

report_title = "Первый квартал года" quarter = 1

Case 4, 5, 6

report_title = "Второй квартал года" quarter = 2

Case 7, 8, 9

report_title = "Третий квартал года" quarter = 3

Case Else

'

'Если текущий месяц имеет номер вне диапазона от 1 до 9,

'то сейчас – четвертый квартал.

'

report_title = "Четвертый квартал года" quarter = 4

End Case

Обратите внимание на предложение Case Else в конце оператора Do Case. Case Else

необязательное предложение. Если оператор Do Case содержит предложение Case Else è

текущее значение выражения не равно ни одному из значений, перечисленных в предложениях Case, MapBasic выполнит операторы, расположенные после предложения

Case Else. Предложение Case Else должно быть последним предложением оператора Do

Case.

48

Глава 4: Основы языка MapBasic

Оператор GoTo

Оператор GoTo используется для перехода в заданное место программы с того места, где встретился оператор GoTo. В операторе GoTo указывается метка перехода; оператор GoTo

не будет работать, если в той же процедуре, где находится оператор перехода, нет метки с таким именем. Метка – это имя, сопоставленное некоторой строке программы и расположенное в начале этой строки; после имени метки должно стоять двоеточие (в операторе GoTo это двоеточие ставить не надо).

If counter < 0 Then GoTo get_out

End If

...

get_out: End Program

Многие профессиональные программисты не одобряют использование операторов перехода типа GoTo. Полноценное использование возможностей других управляющих операторов, таких как If...Then, обычно устраняет необходимость использования оператора GoTo. Так что Вы можете обходиться и без GoTo.

Оператор For...Next

Оператор For...Next определяет цикл, выполняющийся заданное число раз. Каждое повторение состоит в том, что MapBasic выполняет все операторы, находящиеся между For

è Next.

Перед использованием цикла For...Next Вы должны объявить имя числовой переменной, которая будет использоваться в качестве счетчика. Надо указать начальное и конечное значения этого счетчика. После выполнения каждого повтора (после каждой итерации) MapBasic будет увеличивать счетчик на заданную величину (шаг цикла). Стандартный шаг цикла равен единице (1); чтобы задать другой шаг, следует использовать необязательное предложение Step.

Ниже приводится пример использования цикла For...Next для увеличения всех элементов некоторого массива:

Dim monthly_sales(12), grand_total As Float, next_one As SmallInt

...

For next_one = 1 To 12

grand_total = grand_total + monthly_sales(next_one) Next

Начиная выполнять оператор For...Next, MapBasic присваивает переменной-счетчику начальное значение; в приведенном примере, MapBasic присвоит переменной next_one единицу. Затем MapBasic выполняет операторы, расположенные до ключевого слова Next. После каждой итерации цикла MapBasic увеличивает переменную-счетчик. Если счетчик меньше либо равен заданному Вами конечному значению (в примере, если next_one меньше или равна 12), MapBasic выполняет следующую итерацию цикла.

Выполнение оператора For...Next прерывается, если встретился оператор Exit For. Это позволяет при необходимости немедленно остановить цикл.

49

Глава 4: Основы языка MapBasic

Замечание: Åñëè öèêë For...Next использует явно заданные вещественные значения (например, For i = 0.1 to 1.0 Step 0.1), то такой цикл может выполняться в MapInfo для Macintosh иначе, чем в MapInfo для Windows или UNIX (т.е. может быть выполнено разное число итераций на Macintosh и PC под Windows). Это возможно из-за особого способа обработки плавающих вещественных чисел в компьютерах Macintosh.

Подробнее о цикле For...Next ñì. Справочнике MapBasic.

Оператор Do...Loop

Оператор Do...Loop выполняет группу операторов, пока заданное в нем условие остается истинным, либо пока условие остается ложным.

Возможны различные виды оператора Do...Loop, в зависимости от того, когда Вы хотите проверять условие цикла: до или после выполнения операторов, находящихся в теле цикла. В следующем примере программы условие проверяется в конце цикла:

Dim sales_total, new_accounts(10) As Float, next_one As SmallInt

next_one = 1 Do

sales_total = sales_total + new_accounts(next_one) next_one = next_one + 1

Loop While next_one <= UBound(new_accounts)

Обратим внимание, что такой цикл всегда выполняется хотя бы один раз, поскольку условие проверяется лишь в конце цикла (после выполнения первой итерации).

Следующий пример содержит проверку в начале цикла. Поскольку условие проверяется в начале цикла, операторы в теле цикла могут не выполниться ни разу. Если в момент начала выполнения цикла условие уже ложно, операторы в теле цикла Do...Loop не будут выполнены ни разу.

Dim sales_total, new_accounts(10) As Float, next_one As SmallInt

next_one = 1

Do While next_one <= UBound(new_accounts) sales_total = sales_total + new_accounts(next_one) next_one = next_one + 1

Loop

В обоих приведенных примерах оператора Do...Loop используется ключевое слово While; поэтому оба цикла выполняются до тех пор, пока указанное после этого ключевого слова условие остается истинным. С другой стороны, в операторе Do...Loop можно использовать ключевое слово Until вместо ключевого слова While. Если оператор Do...Loop содержит предложение Until, то цикл выполняется, пока контрольное условие остается ложным.

Выполнение оператора Do...Loop прерывается, если обнаружен оператор Exit Do. Это позволяет при необходимости немедленно остановить цикл.

Оператор While...Wend

MapBasic поддерживает также стандартный синтаксис оператора цикла в языке BASIC

While...Wend. Оператор While...Wend почти во всем совпадет с Do While...Loop.

50

Глава 4: Основы языка MapBasic

Если Вы много программировали на BASIC, то Вам может быть удобнее использовать синтаксис While...Wend и в MapBasic. Следует, однако, заметить, что синтаксис оператора

Do...Loop в некоторых аспектах значительно мощнее синтаксиса оператора While...Wend; например, Вы можете прервать выполнение цикла Do...Loop с помощью оператора Exit Do, â While...Wend же такой возможности нет.

Подробнее о цикле While...Wend ñì. â Справочнике MapBasic.

Завершение выполнения программы

Оператор End Program прерывает выполнение MapBasic-приложения, удаляет все пользовательские меню, созданные приложением, и выгружает приложение из памяти.

End Program также закрывает все файлы, открытые в процессе работы приложения (с помощью оператора Open File), но не закрывает открытые таблицы.

Оператор End Program не обязательно следует выполнять в каждой программе. В некоторых ситуациях Вам, наоборот, следует не выполнять оператор End Program. Например, Ваше приложение добавляет свои меню к системе меню MapInfo и Вы хотите, чтобы это приложение оставалось активным в течение всего сеанса работы с MapInfo, поскольку пользователь должен иметь доступ к меню Вашего приложения в течение всего сеанса работы. В таком случае Вам следует проследить, чтобы Ваша программа не выполняла оператор End Program, поскольку End Program остановит выполнение приложения и удалит все созданные Вашим приложением меню. Подробное обсуждение пользовательских меню Вы найдете в главе 6 "Создание пользовательского интерфейса".

Завершение выполнения программы и сеанса работы с MapInfo

Оператор End MapInfo не только останавливает работу приложения MapBasic (так, как это

делает оператор End Program), но также и закрывает MapInfo.

51

Глава 4: Основы языка MapBasic

Процедуры

Процедура (или подпрограмма) представляет собой основную структурную единицу программы на языке MapBasic. Типичная программа на MapBasic состоит из нескольких процедур; каждая такая процедура содержит операторы, вместе выполняющие некоторую конкретную задачу. Разбиение программы на процедуры придает Вашей программе модульную структуру, делает ее удобнее для дальнейшей разработки и поддержки.

Процедура Main

Каждая программа на MapBasic должна содержать по крайней мере одну процедуру, а именно процедуру со стандартным именем Main. При запуске приложения на MapBasic, автоматически начинает выполняться процедура Main из данного приложения.

Следующий пример программы демонстрирует синтаксис объявления и тела процедуры

Main. В этом примере процедура Main выполняет один только оператор Note:

Declare Sub Main

Sub Main

Note "Привет от MapBasic!"

End Sub

Оператор Declare Sub указывает MapBasic, что в программе встретится процедура с заданным именем. Каждой процедуре в программе должен соответствовать один и только один оператор Declare Sub. Причем оператор Declare Sub должен предшествовать телу объявляемой процедуры. Обычно все операторы Declare Sub располагаются в самом начале программы.

Вспомним, что в главе 3 мы говорили, что программа на MapBasic может состоять только из одной строки. Например, фрагмент:

Note "Привет от MapBasic'а!"

является завершенной программой на MapBasic, которую можно откомпилировать и запустить. Даже такая простейшая программа все равно содержит процедуру Main, однако, в таких случаях мы говорим, что процедура Main задана неявно (в примере же выше она была задана явно).

Вызов процедуры

При компиляции приложения MapInfo автоматически начинает с вызова процедуры Main

(независимо от того, явно или неявно она присутствует в программе). Затем процедура

Main может вызывать другие процедуры с помощью оператора Call. Вот пример программы, состоящей из двух процедур: процедуры Main и процедуры с именем announce_date.

Declare Sub Main

Declare Sub announce_date

Sub Main

Call announce_date( )

End Sub

Sub announce_date

Note "Сегодня " + Str$( CurDate() )

End Sub

52

Глава 4: Основы языка MapBasic

Вызов процедур, имеющих параметры

Как и другие BASIC-подобные языки, MapBasic позволяет создавать процедуры с параметрами. Если процедура имеет параметры, то при ее объявлении их следует перечислять в круглых скобках после имени процедуры в операторе Sub...End Sub.

Ниже приводится пример, в котором процедура check_date имеет один параметр (типа Date). Эта процедура проверяет, давно ли прошла дата, указанная в качестве параметра (прошло более 180 дней); если прошло более 180 дней, то процедура устанавливает значение параметра равным текущей дате.

Declare Sub Main

Declare Sub check_date(last_date As Date) Sub Main

Dim report_date As Date report_date = "01/01/94"

Call check_date( report_date )

'В данный момент переменная report_date

'может содержать текущую дату (в зависимости

'от результата работы процедуры check_date). End Sub

Sub check_date(last_date As Date) Dim elapsed_days As SmallInt

elapsed_days = CurDate() – last_date If elapsed_days > 180 Then

last_date = CurDate() End If

End Sub

Передача параметров ссылкой

По умолчанию все параметры процедур в MapBasic передаются ссылкой. При этом применяются следующие правила:

В операторе Call все параметры, передаваемые в процедуру, должны быть именами переменных.

Если в вызываемой процедуре передаваемому ссылкой параметру присваивается новое значение, то изменяется значение соответствующей внешней переменной. Другими словами, процедура может использовать передачу параметров ссылкой для изменения значений параметров-переменных.

Так, в последнем приведенном нами примере в операторе Call в качестве фактического параметра была указана переменная типа Date report_date:

Call check_date( report_date )

В процедуре check_date соответствующий (формальный) параметр носил имя last_date. Когда в процедуре check_date формальному параметру last_date присваивается текущая дата (last_date = CurDate( ) ), MapBasic автоматически изменяет и значение фактического параметра report_date в процедуре Main.

53

Глава 4: Основы языка MapBasic

Передача параметров значением

Иногда бывает неудобно передавать параметр ссылкой. Все такие параметры, передаваемые ссылкой, должны представлять собой имя переменной, а иногда это бывает утомительно (например, если если Вы не заводили переменных нужного типа).

Как и в других BASIC-подобных языках, в языке MapBasic Вы можете использовать передачу параметров значением вместо передачи ссылкой. Чтобы указать, что параметр передается значением, следует применить ключевое слово ByVal перед именем соответствующего параметра в операторе Sub...End Sub.

При передаче параметра значением действуют следующие правила:

В операторе Call (фактические) параметры не обязательно должны быть именами переменных. Вы можете использовать в операторе Call как имена переменных, так и константы и вообще любые выражения.

Если в вызываемой процедуре передаваемому значением формальному параметру присваивается новое значение, то это значение не влияет на соответствующую переменную (фактический параметр) в вызывающей процедуре. Иными словами, передачу значением нельзя использовать для изменения значения фактического параметра.

Следующий пример содержит процедуру (display_date_range), которая имеет два параметра типа Date, передаваемых значением.

Declare Sub Main

Declare Sub display_date_range(ByVal start_date As Date,

ByVal end_date As Date )

Sub Main

Call display_date_range( "1/1", CurDate() ) End Sub

Sub display_date_range(ByVal start_date As Date, ByVal end_date As Date )

Note "Период выдачи сообщений: с " + Str$(start_date) + " по " + Str$(end_date) + "."

End Sub

В данном примере оба параметра в процедуру display_date_range передаются значением. Так, при вызове display_date_range из продуры Main:

Call display_date_range( "1/1", CurDate() )

ни один из параметров не обязан быть именем переменной. Первый параметр (“1/1") является константным выражением типа Date, а второй – выражением, состоящим из вызова функции CurDate( ).

Рекурсивный вызов процедур

MapBasic поддерживает рекурсивные вызовы процедур и функций. Другими словами, процедуры MapBasic могут вызывать сами себя.

Применение рекурсии ограничивается количеством доступной памяти. Каждый раз, когда происходит вызов процедуры или функции, MapInfo запоминает текущие данные в стеке; если таких вызовов слишком много, произойдет ошибка “Недостаточно памяти”.

54

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]