DataEnvironment'y посвящается | |
---|---|
JS Сообщений: 12264 Откуда: Эстония Дата регистрации: 04.09.2000 |
Первая часть:
www.hot.ee или для тех, у кого заблокирован www.hot.ee, между прочим сайт эстонской телефонной компании kodu.neti.ee Вторая часть: www.hot.ee или для тех, у кого заблокирован www.hot.ee, между прочим сайт эстонской телефонной компании kodu.neti.ee После всех споров по-поводу DE так и хочется иногда сказать фразу из рекламы: Как, вы еще не используете DE, тогда мы идем к вам!. А если серъезно, то я бы не стал ругать этот отнюдь не плохой объект. Не было бы его, у меня иногда были бы большие выкрутасы. [i][small][color=Gray]Отредактировано (16.06.04 17:40) ------------------ Knowledge is better than ignorance! Website: juri.foxhelp.eu |
Re: DataEnvironment'y посвящается | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Эх, ну не могу удержаться от того чтоб не прокомментировать маленько (с целью возможно кой чего прояснить/развить дискуссию)
I Про "жесткую пропись пути" - не отметил что как правило пути не прописываются в объектах DE полностью - обычно там относительные пути (относительно размещения формы), просто "умный" Property Window "переводит" относительный путь в абсолютный. Но конечно бывают и ситуации когда прописан полный путь (например когда форма и данные размещены на разных дисках). В первом случае ситуация не столь плачевна - если проект переносится/распространяется без изменения иерархии папок то всё нормально - и даже если иерархия папок изменена, но "изначальной" папки нету (или там нету данных) а "новая" папка выбрана как SET DEFAULT или указана в SET PATH то фокс таки найдёт данные (плохо это конечно - мало ли где он ещё может одноименную таблицу найти - но не смертельно). Во втором случае всё гораздо хуже - начиная от обращения чёрт-те куда (к CD-накопителям, или через сеть к машине разработчика . II Про то "где и когда подменять пути". Нельзя говорить что "не имеем доступа к DE и его методам" - доступ есть, причём именно через переопределение путей в методе DE.BeforeOpenTables работает код предлагаемый самой MS (кстати нехудо было бы и ссылку на это статью KB поместить - всё-же "в тему"). Другой вопрос в том, что это "технологически" невыгодно/неудобно - ибо нехорошо заниматься Copy/Paste в ОО среде Даже если вставлять в этот метод всего 1 строку - вызов соответствующей функции. Ещё один способ - это "просто убрать AutoOpen" - тогда действительно можно пути поменять в Load и потом явно вызвать OpenTables() но это так-же не слишком красиво по тем-же причинам (можно и забыть эту установку сделать, а субклассировать DE стандартными методами нельзя). Предложенный же способ меня не устраивает по той простой причине, что у тебя будет происходить "двойная работа" - сначала автооткрытие всех источников, потом закрытие, подмена путей и повторное открытие - это крайне негативно сказывается на прои зводительности Возикает извечный вопрос "Что делать" - тут могу предложить лишь один способ (коим и пользуюсь поныне и надеюсь в VFP9 MS ничего не "поломала" и он продолжит мне служить - называется он "субклассирование базового класса" Был открыт когда-то давно уважаемым Michael Drozdov, принят за забавную багофичу и забыт, а я вот "подогрел и обобрал" (с) Суть махинации проста до безобразия: 1) определяем класс - замену базового класса DE:
уникальный (для данной формы) код, то надо не забыть вызвать и наш новый псевдо-базовый код через DODEFAULT(). 4) Для снятия хука и восстановления поведения но умолчанию надо убрать объект goDEHook и прочистить мозги фоксу на предмет кеширования данного класса:
III Про то "как хранить пути" - для начала надо определиться с тем, что мы не должны "передавать пути параметрами" и потому нам действительно не принципиально в каком метода будет идти замена. Твоя идея в целом правильна, но вот в деталях... 1) Объект goApp (кстати зачем ты ему поставил префикс локального?) IMHO должен быть гораздо более мощный чем "просто хранилище свойств" и потому не надо стремиться делать его от Empty класса - в Empty классе невозможно определить методы, а значит он нам не годиться 2) Код "заполнения" IMHO весьма специфичен - я бы вообще не стал никакого кода писать - просто сказал что должны быть такие-то и такие-то структуры (у меня кстати именно коллекция и используется - как "подобъект" goApp-а для VFP7 это "моя коллекция" для VFP8 - уже встроенный класс - я специально сделал их "практически идентичными" по интерфейсам). Как доп. аргументы: разные базы могут лежать не просто в разных подпапках одной папки, а например на разных серверах... Да и не нужно обычно добавлять "всё что ни попадётся" в этот список - т.е. идея с внешней настройкой более интересна - например ini/dbf-файл с набором "путей"+"имён". 3) Для простоты я не загружаю в "коллекции путей" всех возможных вариантов, а только 1 - ибо в один конкретный момент времени у меня программа работает только с одной конкретной базой (не в смысле с одной DBC - их то может быть много разных, а в смысле с "набором баз одного предприятия") И для "замены" надо просто перезаполнить эти коллекции и (возможно, даже желательно, но не обязательно) переоткрыть все формы - чтоб не возникало путаницы. 4) Для DBC и для FreeTable я использую 2 разных коллекции "путей" Индексные ключи коллекций - это соответственно имя DBC и имя Free-таблицы. Заполнение коллекций идёт не напрямую, а через методы goApp - OpenDatabase(tcFullPathName, tnMode) (помимо регистрации в коллекции БД ещё и открывается в нужном режиме), SetFreeTableLocation(tcFullPathName) (таблица конечно не открывается Ну и 2 обратных метода: CloseDatabase(tcName) и ResetFreeTableLocation(tcName). IV Про то "как надо заменять пути" - в принципе нормальный подход, пара замеченных тонкостей: 1) DE может и не называться DataEnvironment разработчик может сменить Name (потому надо тогда орг. вопростом это решать). 2) У тебя рассмотрен только вариант "всё в одной папке", а вполе возможно что БД разнесена по разным папкам (особенно если подсистема сложная - у нас даже для Clipper программ были особые папки скажем для НСИ). Для сравнения приведу и свой код - может какие идеи пригодяться
Зато видим вызов m.goApp._DEBeforeOpenTablesHook - этот метод объекта приложения переключает датасессию (чтоб код мог работать в DS нашей формы) и вызывает абстрактный метод m.goApp.DEBeforeOpenTablesHook() - это хорошее место для размещения всякого установочного кода, который нужен для всех форм/отчётов в приложении - программируется прикладным программистом исходя из его предпочтений - пресловутые SET TALK OFF, SET DELETED ON, SET DATE GERMAN и всё-всё-всё прочее что "scope to the current datasession" - MS VFPTeam не удосужилось никак этот аспект улучшить (например "наследовать" установки Public или просто текущей DS для всех вновь создаваемых DS) так мы их сбоку обойдём Да что-то меня сегодня потянуло на демагогию Есть ещё и конструктивная критика по другим статьям (кой чего ну просто просится чтоб "уточнить и расширить") но это в другой раз. ------------------ WBR, Igor |
Re: DataEnvironment'y посвящается | |
---|---|
JS Сообщений: 12264 Откуда: Эстония Дата регистрации: 04.09.2000 |
2Игорь! Спасибо за отличный и подробный комментарий, будем потихоньку развивать дискуссию.
А так как сегодня не дадут нормально пообщаться - ревизия архивов - то отвечать и задавать вопросы буду частями. Цитата:По-поводу относительного пути - мое упущение и об этом стоило написать сразу - это предмет для редактирования статьи (пора уже, наверное, вместе писать) и об этом речь идет в третьей части, и как раз здесь большинство новичков спотыкается - при работе со свойствами DataEnvironment. Я еще не успел отредактировать остальные части - всего 7 (первые три - DataEnvironment, как native form object, последующие три - DataEnvironment, как класс и последняя - тестовое приложение, где есть ссылка на него и описание). Цитата:Игорь! В статье я имею в виду собственный базовый класс формы и классы форм, выстраиваемые на ее основе, что иногда вызывано необходимостью иметь строго "прорисованную" и вылизанную форму, и с которыми работаем в визуальном дизайнере классов. При работе с классом формы мы действительно не имеем возможности работать с DataEnvironment. Здесь может быть несколько неудачно получилось с рисунками - для того, чтобы показать свойства и методы DE пришлось делать это не в дизайнере классов, а в дизайнере форм. (Это тоже может сбивать с толку и надо подумать, как получше отобразить это графически). А вот когда уже мы работаем с формой, создаваемой на базе класса, в дизайнере форм, то мы уже конечно можем работать с методами событий объекта DataEnvironment, хотя при этом теряются преимущества OOP, то есть должны каждый раз прописывать код в соответствующих методах и как справедливо замечено - что это "технологически" невыгодно/неудобно - ибо нехорошо заниматься Copy/Paste в ОО среде. И это тоже нужно будет подкорректировать в статье. Что же касается статьи 160916, то она уже переведена и ссылка на нее в третьей части. Цитата: Давай посмотрим на третий абзац второй части: Цитата: Справедливо и не используется мною в реальных проектах. То есть когда разрабатывается форма на основе подобного класса в дизайнере форм, то свойство AutoOpenTables всегда устанавливается в .F. Это вроде бы видно из примера кода, однако можно подчеркнуть особо. В класс формы можно ввести свойство типа fvl_UseAutoOpenTables (по умолчанию устанавливается в False) и ввести его проверку в методе события OpenTables, но опять-таки надо прописать код и хотя он короче, но он все-таки есть, например:
This.fvl_UseAutoOpenTables=.T. Поскольку еще в первой части я оговорил, что данное применимо к структуре концерна или необходимостью работы с одинаковыми базами, то нужно некоторое пояснение. Имеются реальные приложения, первое было сделано на VFP 6.0 для своего приятеля - присяжного адвоката (опять-таки бесплатно - программист и бизнесмен в одном стакане вещь трудно совместимая, особенно когда речь идет о друзъях), который ведет дела нескольких фирм (присяжные адвокаты занимаются не только судебными делами, но и разными международными договорами, декларированием и массой других разных дел и в общем-то объемы данных весьма приличные). И иногда ему нужны тождественные документы. Все было сделано на описанном принципе, когда он просто в форме через combobox выбирает другую фирму, просматривает или копирует какие-то уже готовые решения (поэтому и используются вылизанные до "абсурда" классы). И в статье приведено, конечно же, упрощенное:
Это его любимая фраза - неладно что-то в Датском королевстве. Идем далее От: Цитата:и до: Цитата: Абсолютно справедливо. Уже сам по себе направшивается вопрос - может быть добавить вводную статью и для начала описать все возможности создания DE от программного до класса (VFP8) и последующей работы с ним? поскольку приведенные статьи рассматривают частный пример использования... А что касается стандартных фоксовский отчетов, то я использую их редко. В основном перегонка в подготовленные шаблоны Excel или Word. Цитата: Согласен, здесь немного некорректное использование префикса, так как не хотел чего-то придумывать и в данном случае они означают localization object, сюда заносятся то что уже показано и установки из ini-файла и из регистра. В первых строках идет вызов процедуры декларирования динамических библиотек, размещенной здесь же. Поскольку здесь только фрагмент, то не стал править, а вообщем-то учту. Что же касается использования Empty класса, то меня в данном случае он как раз устраивает, так как хранит только установки, которые доступны повсюду в приложении. Для обслуживания приложения создается объект диспетчера (я это так называю, может быть неудачно, но тут уж сила привычки), который на базе установок определяет наличие обновления, осуществляет кое-какие проверки, что-то грузит дополнительно и так далее. Вот он называется dspApplication и тождественнен по смыслу, но не функциональности goApp, как это использовалось начиная с третьей версии. Цитата: Для примера хоть что-то показать надо. [i][small][color=Gray]Отредактировано (17.06.04 16:31) ------------------ Knowledge is better than ignorance! Website: juri.foxhelp.eu |
Re: DataEnvironment'y посвящается | |
---|---|
Igor Korolyov Сообщений: 34580 Дата регистрации: 28.05.2002 |
Сразу скажу что когда писал, только первую часть просмотрел потому и
часть непоняток возникла. Цитата:Тогда это надо подчеркнуть - что это именно классы форм, а не scx-формы, а то возникает законный вопрос - вот я смотрю на DE формы, а мне говорят что его нету Кстати я пока что не вижу реальных преимуществ "отвязанного DE - класса". Т.е. не сталкивался с такими ситуациями, когда много форм используют идентичные DE - обычно всегда возникают какие-то вариации, и реально каждая форма имеет свой уникальный набор курсоров/связей в DE. А значит в плане субклассирования достаточно иметь просто 1 _base класс DE (пустой) и массу "конечных" DE-классов/объектов т.е. то как оно изначально было задумано MS-ом... Реально субклассированием непустого DE я так и не занялся... Да и тут скорее нужно не субклассирование, а "агрегирование" - т.е. из 2-х имеющихся DE слепить один новый - да так чтобы ничего не пересекалось и не взаимодействовало "неясным образом". Вот тут пока самое слабое место что я вижу в DE... Как можно привязать DE к некоторому контейнеру, как можно организовать взаимодействие нескольких DE в одной форме и одной датасессии соответственно... Пока только вопросы без ответов. Цитата:А оно к тому моменту уже доступно? В режиме AutoOpen когда порядок срабатывания событий "особый" (некоторые даже говорять что это ужасно криво и неправильно - типа до Init ничего срабатывать не должно) Цитата:А, ну тогда понятно... Хотя тут можно сделать разделение по иному принципу - завести общую базу "шаблонов", и копировать исключиетльно из неё, а не "от чужой фирмы"... И кстати структура "общей базы" где разделение сделано только по полю "код предприятия/клиента" тоже может быть применено. Но это так - к слову. Цитата:Так только один этот класс-хук описан невизуально Все формы то визуальные! его прелесть как раз в том, что не приходится отказываться от визуальных дизайнеров, как порой требуется в случае с "внедрением своего класса DE" - особливо в VFP6SP5... Он вообще работает "из-под" т.е. прозрачно для всего остального - они и не подозревают что вместо "фоксового базового класса DE" используется моя прослойка. За единственным исключением - переопределением методов - тогда надо "вспомнить" что есть ещё и мой код и вставить DODEFAULT() Цитата:IMHO сильно обширно получится и будет только путать новичка... Просто скажи что это один из возможных путей,а про другие только упомяни (перечисли) если уж так решил. Цитата:У меня тоже ------------------ WBR, Igor |
Re: DataEnvironment'y посвящается | |
---|---|
JS Сообщений: 12264 Откуда: Эстония Дата регистрации: 04.09.2000 |
Цитата: В том и анекдот, что уже доступно, хотя форма вроде как бы и не загружена. Цитата:Игорь, пока ты, видимо, еще читал, я уже поправил. Какая-то отвязка происходит когда видишь define class - сразу переключаешься на процедурное... Извини! Цитата:Шаблоны здесь не совсем подходят, хотя и используются. Копируются какие-то фрагменты ранее удачно составленного текста, или признаковая группа (это он так называет - "в соответствии со статьей nn § nn закона" и т.п. Я уж ему и словарь фраз сделал, говорит, что так привычнее, сразу видит проблему, но это уже так - отвлеклись. Цитата: Я думаю, что здесь есть определенная связь между введенными в 8-й версии классами DE и CursorAdapter, и это предположение основано на том, что построитель DE "заточен" под работу с последним. Даже если мы создадим класс обычного курсора и потом попробуем добавить его в DE с помощью построителя, мы получим ошибку - <имя_курсора> is no CursorAdapter subclass. Но опять-таки - это только предположение. Хотя без всяких проблем мы можем вставить тот же заготовленный класс обычного курсора в класс DE в дизайнере классов без всяких проблем. И вообще в документации есть несколько противоречий. Но об этом позже. [i][small][color=Gray]Отредактировано (18.06.04 12:34) ------------------ Knowledge is better than ignorance! Website: juri.foxhelp.eu |
Re: DataEnvironment'y посвящается | |
---|---|
Sergey Titow Автор Сообщений: 2242 Дата регистрации: 12.09.2000 |
Цитата:Это не некоторые - это сам прародитель этой объектной схемы. И не в "режиме AutoOpen", а при AutoOpen=.t. в случае scx формы. И не просто "до Init" самого объекта - а даже до Load его родителя PS. Я уже говорил, что это надо было только для заточки под визуальную среду разработки. В ран-тайме это вообще ни для чего не надо. И "ужасную кривость" вижу не в том, что это сделано именно так, а в том, что именно так M$ поступает всегда, когда "спирт мешает спорту". И до сих пор не понимаю, почему ДЕ нет в качестве стандартного члена класса формы... PPS. Искать способ применения багофич - занятие на любителя. Для меня лично - удовольствие ниже среднего. [i][small][color=Gray]Отредактировано (20.06.04 18:40) ------------------ |
© 2000-2024 Fox Club  |