понедельник, 25 ноября 2013 г.

Советы шеф-повара: обновление данных в таблицах

Основная ценность, при работе практически с любыми программами, это данные. У программы, занимающейся работой с данными, должны присутствовать механизмы ввода, редактирования, сохранения данных.
В Mapinfo данные хранятся в таблицах и могут содержать две составляющие: графические и семантические данные. Со стороны Mapinfo, каждая таблица представляет собой нечто целое, содержащее некоторые записи, у каждой записи обязательно есть минимум одно семантическое поле. Со стороны файловой системы, таблица Mapinfo состоит из нескольких файлов, в каждом из которых содержится какая-то информация: семантика, графика, служебная информация, индексные файлы.
Сегодня я захотел написать о редактировании данных, так как это неотъемлемая часть процесса подготовки картографического материала. Ко всем прочему, в форумах регулярно возникают вопросы, связанные с "а как...?"

Я бы разделил возможности по редактированию на три группы:
1. ручное редактирование
2. полуавтоматизированное редактирование
3. автоматизированное редактирование

1. Ручное редактирование.
Дешево, надежно и практично. Графические объекты редактируются в окне карты, семантические поля - в окне списка или в окне информации. Хотел бы обратить внимание, что при редактировании таблиц, имеющих графические объекты (Mappable), через окно списка можно создавать записи без графических объектов. Это делается простым добавлением новой записи в окне списка. В последующем, прицепить к таким записям графические объекты, проблематично для неподготовленных пользователей. Если в такой таблице нужно добавить новый графический объект, но необходимо открыть эту таблицу в окне карты и нарисовать нужный графический объект.

2. Полуавтоматизированное редактирование.
Под полуавтоматизированным методом я понимаю редактирование с использованием
окна Mapbasic, построителя запросов и прочих штатных встроенных инструментов Mapinfo.
Для полноценного использования такого метода, на мой взгляд, нужны знания языка Mapbasic. Сложности в нем нет, но есть особенности версий, есть особенности Mapinfo, есть некоторые ограничения на использование Mapbasic в одноименном окне Mapinfo. Как я уже упоминал в ранних постах, документация Mapinfo и Mapbasic на очень хорошем уровне, и даже самостоятельное изучение не вызовет проблем.
В качестве живого примера полуавтоматизированного обновления приведу простой пример. Возникла элементарная и показательная задача по замене двойных кавычек на одинарные в поле таблицы.Хоть Mapbasic и довольно развитый язык, но, в основном, он содержит базовые(элементарные) функции. И строковой функции "ЗаменитьПодстроку" в нем нет. Зато есть огромное поле для фантазий по решению задачи с использованием ограниченного набора инструментов. Решение простое :-). Пара команд:

select * from SrcTable where InStr(1, SrcField, SrcSubstring) > 0 into TmpTable noselect

update TmpTable set SrcField = Mid$(SrcField, 1, InStr(1, SrcField, SrcSubstring) - 1) + NewSubString + Mid$(SrcField, InStr(1, SrcField, SrcSubstring) +Len(SrcSubstring) , 254)

Выполняем эту пару два раза получаем решенную задачу...

Первая команда select дает нам выборку записей исходной таблицы, в исходном поле которой есть требуемая для замены подстрока (в нашем случае - символ двойной кавычки ["]). В результате мы получаем запросную таблицу TmpTable. Теперь любые изменения в записях таблицы TmpTable автоматически записываются в соответствующие записи исходной таблицы SrcTable. Кто-то может спросить: а почему нельзя сразу написать update SrcTable ...?
Использование промежуточной таблицы обусловлено тем, что прямой update может вызвать ошибку, в случае если встретится запись, в которой в просматриваемом поле не искомой подстроки. Перехватывать ошибки в окне Mapbasic невозможно, поэтому используется промежуточная таблица.
  Вторая команда (update...) производит замену нашей SrcSubstring на NewSubString.
  Просто и быстро.
  Если надо произвести изменение графического объекта, то команда может выглядеть следующим образом:

update SrcTable set obj = ConvertToPLine(obj)
эта команда превратит все графические объекты в полилинии.

update SrcTable set obj = CreatePoint(x,y)
а эта команда создаст для каждой записи точечный объект, при условии что в таблице есть поля x и y с координатами.

3. Автоматизированное редактирование.
Под автоматизированным редактированием я понимаю использование специализированной программы на языке Mapbasic.
Это, пожалуй, универсальный метод, позволяющий реализовать все что душе угодно. С опытом, каждый для себя сможет сформулировать критерии, по которым можно принимать решение о выборе подхода, для решения вопроса о редактировании данных. Зачастую, написать пару команд в окне Mapbasic позволяет выполнить задачу быстрее, нежели подготовка самой простой программы на Mapbasic.
Простейшая программа для наших целей будет содержать всего две функции : обязательную main и пользовательскую, которая производит обработку строки.

sub main
  update TmpTable set SrcField = StringReplace(SrcField, SrcSubstring, NewSubString )
end sub

function StringReplace(byval aStr as string, byval aOldSub as string, byval aNewSub as string) as string
...
  StringReplace = ...
end function

Что мы имеем?
В коде присутствует обязательная для каждой программы Mapbasic sub main, в которой происходит обновление поля таблицы.
Функция StringReplace() производит обработку значения поля SrcField: заменяет все вхождения SrcSubstring на NewSubString.
Если нужна функция для обработки графических объектов, то ее объявление может иметь следующий вид

function ModifyObject(byval aObj as object) as object
...
  ModifyObject = ...
end function

В программе можно использовать все возможности Mapbasic. Остается откомпилировать текст программы при помощи компилятора Mapbasic и запускать ее на выполнение.

Вот, пожалуй, и все. Общая тема обозначена, все остальное - дело техники и опыта. Не бойтесь изучать, экспериментировать и думать.

Комментариев нет: