Kaspersky Worm Removal Tool 10.1.2.1 - Компактная антивирусная программа для удаления интернет-червей. Удаляет Klez, Sircam, Lentin, Goner, Lovesan/MSBLAST, Worm.Win32.Sasser.a,b,c и некоторых других червей.
Avira AntiVir Personal 8.2.0.337 - Антивирусная программа. Определяет и удаляет вирусы и трояны, в том числе и еще неизвестные макровирусы, есть возможность постоянного мониторинга системы.
AntiVir Personal бесплатна для "домашнего", т.е. индивидуального и некоммерческого, использования.
Программа может работать как на 32-, так и на 64-битных системах.
Ссылка "скачать" - версия с английским интерфейсом (с оф.сайта можно скачать вариант с интерфейсом на немецком языке).
В качестве расплаты за бесплатность при каждом обновлении базы данных показывается во весь экран монитора рекламное окно, призывающее купить платную версию этой программы.
Dr.Web CureIt! 3.01.2009 (Portable) - бесплатный антивирусный сканер на основе ядра антивирусной программы Dr.Web, который быстро и эффективно проверит и вылечит компьютер без установки самого антивируса Dr.Web.
Dr.Web CureIt! определяет и удаляет почтовые и сетевые черви, файловые вирусы, троянские программы, стелс-вирусы, полиморфные, бестелесные и макровирусы, вирусы, поражающие документы MS Office, скрипт-вирусы, шпионское ПО (Spyware), программы-похитители паролей, программы-дозвонщики, рекламное ПО (Adware), Хакерские утилиты, потенциально опасное ПО и любые другие нежелательные коды.
Интерфейс - более чем на 30 языках. Работает Dr.Web CureIt! без инсталляции.
Расплата за бесплатность: В программу не входит модуль автоматического обновления вирусных баз, поэтому для того, чтобы просканировать компьютер в следующий раз с самыми последними обновлениями вирусных баз, нужно будет снова скачать Dr.Web CureIt!
Интерфейс CureIt! - многоязычный (35 языков).
В данной статье приведены общие сведения об организации работы системы 1С:Предприятие с распределенной информационной базой (ИБ). Также описаны внутренние особенности организации механизма работы с распределенными данными для того, чтобы специалисты, осуществляющие конфигурирование и администрирование распределенных систем могли лучшее понимать выполняемые системой действия. Данная информация может также быть использована для оценки дополнительных затрат ресурсов системы, расходуемых на поддержание распределенной информационной базы.
Так как средства системы 1С:Предприятие для работы с распределенными информационными базами поставляются отдельно, сначала кратко остановимся на назначении и основных принципах организации работы системы 1С:Предприятие с территориально удаленными подразделениями.
Назначение и основные принципы
В тех случаях, когда предприятие представляет собой территориально распределенную структуру, зачастую сохраняется потребность в ведении единой системы учета. То есть необходимо иметь возможность работать в едином пространстве документов, получать отчеты, отражающие состояние дел как в территориально удаленных подразделениях предприятия, так и на предприятии в целом и т.п. При этом не всегда имеется возможность организовать работу всех подразделений с единой информационной базой в режиме он-лайн.
Для решения подобных задач предназначена компонента "Управление распределенными ИБ". С помощью указанной компоненты можно организовать двухуровневую структуру информационных баз (ИБ) системы 1С:Предприятие, состоящую из одной центральной и нескольких периферийных информационных баз, работающих с единой конфигурацией. При этом система будет стремиться поддерживать одинаковое состояние объектов данных во всех узлах распределенной ИБ.
Содержимое информационных баз синхронизируется путем переноса измененных объектов данных между каждой из периферийных и центральной ИБ. Для переноса данных используются так называемые файлы переноса данных. Перенос изменений выполняется только между центральной и периферийными ИБ. Перенос данных непосредственно между периферийными ИБ невозможен. Поэтому изменения данных, произведенные в одном из периферийных узлов распределенной ИБ попадают в другие периферийные узлы только через центральную ИБ.
В простейшем случае (по умолчанию) областью распространения изменений для всех объектов является вся распределенная ИБ. Таким образом, в случае если в течение какого-то времени изменения данных системы не будут производиться, и, в то же время, будут произведены все необходимые действия по обмену изменениями между узлами распределенной ИБ, то все узлы будут содержать абсолютно одинаковые данные.
В некоторых случаях может возникнуть необходимость в том, чтобы объекты того или иного типа никогда не попадали в те или иные узлы распределенной ИБ или никогда не покидали места своего создания. Для обеспечения такой возможности предназначен механизм настройки параметров миграции объектов. С его помощью можно ограничить распространение изменений объектов того или иного вида. Кроме того, в версии 7.7 системы 1С:Предприятие можно создавать периферийные ИБ, которые будут принимать информацию о измененных объектах из центральной ИБ, но не будут передавать изменения, сделанные в них самих.
Механизмы распространения изменений объектов работают полностью автоматически. Разработчик конфигурации лишен возможности вмешиваться в функционирование этих механизмов. Для того, чтобы механизмы распределенной ИБ начали работать, не нужно производить никаких специальных действий по конфигурированию системы.
Однако, для того, чтобы документы, элементы справочников и другие объекты, созданные в разных узлах распределенной ИБ, имели заведомо непересекающиеся пространства номеров, кодов и т. п., может потребоваться внести в конфигурацию некоторые изменения. Также изменения в конфигурации должны вноситься при необходимости обеспечить специальные ограничения работы пользователей на периферийных информационных базах.
Для переноса измененных объектов в распределенной ИБ и для первичного создания периферийной ИБ используется файл переноса данных. Он представляет собой упакованный (сжатый) файл, содержащий объекты информационной базы (все при создании периферийной ИБ или измененные при передаче изменений) в специальном формате. Формат данного файла не предназначен для использования его способами отличными от тех, которые предусмотрены механизмами выгрузки/загрузки и передачи изменений. Файл переноса фактически отражает содержимое объектов информационной базы в формате, не зависящем от формата базы данных. Это позволяет использовать в распределенной информационной системе в различных узлах различные форматы хранения данных, поддерживаемые системой 1С:Предприятие (DBF/CDX и MS SQL Server).
Регистрация изменений
Перенос измененных данных производится "пообъектно". То есть единицей переноса данных является так называемый ведущий объект. С точки зрения работы в распределенной информационной базе в 1С:Предприятии существуют следующие типы ведущих объектов:
константа,
элемент справочника,
документ,
календарь,
счет бухгалтерского учета,
типовая операция.
Вместе с документами переносятся все действия, выполняемые ими в процессе проведения: движения регистров, акты расчета, бухгалтерская операция, проводки. В случае, если при проведении документа производятся изменения периодических реквизитов элемента справочника, то производится перенос всего элемента справочника.
Регистрация изменений объектов производится автоматически при любом изменении объекта, независимо от того каким способом это изменение производилось (интерактивно или из встроенного языка). Кроме того в версии 7.7 системы 1С:Предприятие для таких объектов как элементы справочников и документы появилась возможность управления регистрацией изменений. Для этого у соответствующих объектов метаданных введен признак "Автоматическая регистрация изменений". Если этот признак установлен (значение по умолчанию), то автоматическая регистрация производится, а если признак сброшен, то регистрация не производится и изменения объектов в распределенной ИБ не распространяются. Но и в данном случае, при выполнении записи изменений объектов из встроенного языка можно управлять регистрацией изменений с помощью метода встроенного языка РегистрацияИзменений().
Регистрация изменений ведущих объектов производится в специальной служебной таблице. При этом фиксируются следующие данные об изменении объекта:
Сам ведущий объект;
Идентификатор той ИБ, в которую должно быть передано изменение;
Идентификатор ИБ, в которую должно быть передано изменение, служит для отслеживания переноса данных в каждую из ИБ, с которой данная ИБ обменивается данными. Таким образом, при изменении какого-либо объекта в центральной ИБ в таблицу будет помещено по одной записи для каждой из зарегистрированных периферийных информационных баз. Если же изменение объекта происходит в периферийной ИБ, то в таблицу будет занесена только одна запись, соответствующая центральной ИБ, так как каждая из периферийных ИБ непосредственно взаимодействует только с центральной.
Заметим, что удаление объекта является частным случаем изменения. Оно также помечается в таблице регистрации изменений и передается при выгрузке.
Выгрузка и загрузка изменений
Каждая выгрузка изменений осуществляется в адрес конкретной ИБ. В файл переноса, создаваемый при выгрузке попадают все объекты, записи об изменениях которых содержатся в таблице регистрации изменений для данной ИБ.
Заметим, что выгружаются не изменения объектов, а сами измененные объекты. То есть, если в документе изменилось значение одного реквизита, то будет передаваться весь документ и он будет полностью перезаписан на той ИБ, в которую переносится. Как уже отмечалось, вместе с документом будут перенесены и сделанные им движения регистров, операция и проводки. Если изменяется любой реквизит справочника, то передается полностью весь элемент. При этом история периодических реквизитов передается целиком. Последнее означает, что изменения сделанные в истории периодического реквизита элемента на в двух ИБ не будут сливаться вместе.
В процессе выгрузки в таблице регистрации изменений отмечается выгрузка изменений объектов.
При загрузке файла переноса данных помимо загрузки измененных данных выполняется так называемый прием подтверждений.
В случае, когда пришло подтверждение на получение выгрузки, содержащей последнее изменение объекта, запись об изменении удаляется из таблицы регистрации. То есть записи об изменении объектов данных хранятся в таблице регистрации до тех пор, пока не будет получено подтверждение о доставке измененного объекта по назначению.
Причем выгрузка измененного объекта будет производиться до тех пор, пока не будет получено подтверждение, о доставке изменения. Это значит, что если выполнять перенос все время в одном направлении и не выполнять обратного переноса то объем файла переноса данных будет все время расти, так как каждый раз будут передаваться все объекты, измененные после последнего полученного подтверждения.
При загрузке изменений объектов из периферийной ИБ в центральную, в таблицу регистрации изменений (если, конечно, параметры миграции настроены соответствующим образом) заносятся записи, указывающие, что загруженные из периферийной ИБ изменения объектов должны быть переданы в другие периферийные ИБ.
Изменения конфигурации
Как уже отмечалось, при работе с распределенной ИБ, конфигурация системы может быть изменена только в центральном узле.
Для регистрации изменений конфигурации и передачи ее на периферийные ИБ используется тот же механизм, что и для объектов данных. При записи измененной конфигурации, в таблицу регистрации изменений объектов по числу известных периферийных ИБ заносятся записи, фиксирующие факт изменения конфигурации.
После записи измененной конфигурации в распределенной ИБ складывается такая ситуация, что центральная и периферийные ИБ работают фактически с разными конфигурациями. В таком состоянии созданные на периферийной ИБ файлы переноса данных не могут быть загружены на центральной ИБ по той причине, что в условиях различных конфигураций содержащаяся в файле информация не может быть правильно интерпретирована. Обмен будет восстановлен только после того, как в периферийную ИБ будет загружена измененная конфигурация с центральной ИБ. То есть после изменения конфигурации требуется выполнить перенос из центральной ИБ в каждую из периферийных, а уже затем выполнять перенос из периферийных ИБ в центр.
Перенос измененной конфигурации в периферийные ИБ осуществляется тем же способом, что и перенос измененных объектов данных. В процессе очередной выгрузки из центральной ИБ, в файл переноса данных целиком включается измененная конфигурация, если, конечно, в таблице регистрации изменений содержится запись о том, что измененную конфигурацию следует передать в соответствующую периферийную ИБ. Выгрузка конфигурации также будет производиться до получения извещения о приеме измененной конфигурации.
Заметим, что конфигурация считается измененной при любых изменениях метаданных, форм, модулей, таблиц конфигурации, наборов прав, пользовательских интерфейсов, описаний. В состав конфигурации не входит список пользователей, а также внешние по отношению к файлу конфигурации (1CV7.MD) файлы (внешние отчеты, отдельно записанные таблицы и тексты). И эти внешние файлы не переносятся механизмом управления распределенной ИБ. Поэтому при конфигурировании распределенной системы не рекомендуется использовать в конфигурации находящиеся в отдельных файлах модули, таблицы и отчеты.
Для изменения уже работающей конфигурации можно рекомендовать использовать механизм загрузки измененной конфигурации. Он позволяет специалисту скопировать конфигурацию, выполнить в ней все необходимые изменения, отладить внесенные изменения (этот процесс может занять и несколько дней), а затем загрузить измененную конфигурацию в центральную ИБ, после чего изменения будут распространены на все периферийные ИБ с очередной передачей изменений. Такая последовательность позволит избежать многократной передачи измененной конфигурации в периферийные ИБ в процессе ее модернизации.
При загрузке файла переноса данных на периферийной ИБ, этап загрузки измененной конфигурации (если, конечно, она содержится в файле переноса данных) предшествует этапу загрузки измененных объектов данных. В случае неудачного завершения загрузки конфигурации, загрузка объектов данных производиться не будет и информационная база останется в том же состоянии, что и была до начала загрузки.
Загрузка измененной конфигурации может завершиться неудачей, если измененная конфигурация не соответствует существующим данным. Например, было уменьшено число уровней справочника, а новое число уровней оказывается меньшим, чем фактически содержащееся в справочнике или в других подобных случаях. Если такое произошло, то следует привести данные в соответствие с новой конфигурацией или изменить конфигурацию в центральной ИБ и заново произвести выгрузку, чтобы ликвидировать возникшее противоречие.
Коллизии
При работе в реальных распределенных ИБ один и тот же объект может изменяться одновременно в различных узлах распределенной ИБ. И при переносе измененных объектов из одной ИБ в другую может случиться так, что в какую-либо ИБ будет загружаться объект, зарегистрированный в самой этой ИБ как измененный. Такая ситуация носит название коллизии. Приведем описание действий системы в наиболее типовых вариантах коллизий.
Один и тот же объект изменен более чем в одной ИБ.
Общий принцип здесь состоит в том, что "главным" считается изменение, произведенное в центральной ИБ. Отработка ситуации различается в зависимости от того, на какой ИБ - центральной или периферийной коллизия обнаружена. Если коллизия обнаружена на центральной ИБ, то есть при загрузке файла переноса из периферийной ИБ обнаружено, что один из измененных объектов также изменен и в центральной ИБ, то изменения объекта в центральную ИБ не загружаются. При этом гарантируется, что при очередной выгрузке в адрес периферийной ИБ будет передано состояние объекта как оно есть в центральной ИБ. Если же коллизия обнаружена на периферийной ИБ, то изменения объекта, прибывшие из центральной ИБ загружаются.
Объект, измененный в одной ИБ, удален в другой.
В данном случае принцип заключается в том, что изменение всегда "главнее" удаления. В случае, если на центральную ИБ прибывает файл переноса, в котором содержится информация, что некоторый объект удален на периферийной ИБ, то в центральной ИБ объект не удаляется, а в записи таблицы регистрации изменений данный объект помечается как измененный. То есть при очередном обмене объект будет восстановлен в той ИБ, в которой он был удален, причем само содержание объекта будет соответствовать той ИБ, которая "отвергла" удаление.
Аналогичные действия производятся, если коллизия обнаружена на периферийной ИБ.
Объект, удаленный в одной ИБ, не может быть удален в другой по причине наличия ссылок на него.
При загрузке изменений, если загружается информация об удалении объектов, автоматически включается механизм контроля ссылочной целостности и выполняется проверка наличия ссылок в данной ИБ на объекты, которые переданы как удаленные.
В случае обнаружения коллизии такого рода, вне зависимости от того на какой из ИБ она была обнаружена, выполняется следующее: удаление не выполняется, а в таблицу регистрации изменений заносится запись о том, что объект должен быть перенесен в адрес той ИБ, из которой была прислана информация о его удалении.
При очередном обмене объект восстанавливается в той ИБ, в которой он был удален, однако само содержание объекта будет соответствовать той ИБ, которая "отвергла" удаление.
Таким образом, управление распределенной информационной базой имеет определенную стратегию автоматического разрешения любых коллизий с описанными приоритетами. Однако, в реальных условиях рекомендуется средствами конфигурации определить возможные действия пользователей на различных узлах таким образом, чтобы исключить или минимизировать вероятность возникновения коллизий. Основным путем является определения средствами конфигурации "ответственного" узла за каждый ведущий объект в распределенной ИБ и ограничение всем остальным возможности его редактирования и удаления. Определение "ответственных" должно происходить исходя из логики работы предприятия. Очевидно, что многие виды объектов можно разрешить изменять только в центральной ИБ (например, список складов). Для многих объектов можно рекомендовать средствами встроенного языка установить возможность изменения только на той ИБ, на которой они созданы, например для документов.
Параметры миграции
С помощью настройки параметров миграции можно ограничивать области распространения изменений объектов. Настройка параметров миграции происходит по видам "ведущих" объектов. То есть для каждого вида "ведущих" объектов можно определить конкретную настройку параметров миграции. В настройке параметров миграции объектов ведущую роль играет выбор того или иного варианта области распространения изменений объектов данного вида. Существуют три варианта настройки области распространения:
Все информационные базы. Данный вариант настройки используется по умолчанию для всех объектов. В этом случае любые изменения объектов данного типа будут распространяться по всем узлам распределенной ИБ. Этот вариант обеспечивает полную синхронизацию объектов данного вида во всей распределенной ИБ. Очевидно, что этот вариант наиболее прост для конфигурирования.
Место создания. Данный вариант настройки также является довольно простым. В этом случае изменения объекта не передаются в другие ИБ. При такой настройке параметров миграции, объект данного вида никогда не "покидает" места своего создания и не появляется в других ИБ. Однако при выборе данного варианта следует учитывать возможные ссылки на объекты данного вида из объектов других видов, имеющих другие параметры миграции. Например, если установить такой вариант для справочника, и в документах, которые участвуют в обмене, будет содержаться реквизит типа справочник данного вида, то при переносе документа получится неразрешенная ссылка.
Место создания и центр. При таком варианте настройки области распространения объектов существенную роль играет понятие места создания объекта. Местом создания объекта считается ИБ, в которой был создан конкретный объект. Естественно, что различные объекты одного вида могут быть созданы в различных ИБ. Однако место создания объекта может быть определено не для всех видов "ведущих" объектов. Для таких объектов как константы, календари или корректные проводки место создания не определено. Поэтому для этих видов объектов вариант настройки "Место создания и центр" не может быть установлен.
В случае выбора такого варианта области распространения, объекты данного вида помимо места их создания попадают еще и на центральную ИБ. То есть, в случае, если для некоторого вида объектов установлена область распространения "Место создания и центр", то для объектов этого вида, созданных на периферийной ИБ, их изменения будут передаваться между местом их создания и центральной ИБ. Для объектов того же вида, созданных на центральной ИБ, изменения не будут передаваться никуда. С помощью такого варианта области распространения можно добиться такого эффекта, что все объекты того или иного вида будут "собираться" на центральной ИБ, а на любой из периферийных ИБ будут находиться только те объекты, для которых она является местом создания.
В случае выбора области распространения "Место создания и центр", для вида объекта можно задать перечень периферийных узлов распределенной ИБ, которые дополнительно включаются в область распространения всех объектов данного вида. Этот перечень задается как список кодов периферийных ИБ, разделенный запятыми. При задании кодов ИБ допускается использование символов-заменителей '*'. Символ-заменитель должен завершать последовательность символов, образующих код одной или нескольких периферийных ИБ. Таким образом, "A*" представляет собой обозначение всех периферийных ИБ, коды которых начинаются символом 'А'. Последовательность "A*B" является ошибочной, так как символ '*' не завершает последовательность символов, представляющих код периферийной ИБ.
Кроме того, как отмечалось выше, дополнительной возможностью управлять распространением изменений объектов в версии 7.7 системы 1С:Предприятие является особый вид периферийных ИБ, которые получают изменения из центральной ИБ, а сами информацию о сделанных в них изменениях не передают. Для создания периферийной ИБ такого рода, надо при ее инициализации указать признак "Только получатель".
Отдельно стоит рассмотреть случай, когда параметры миграции объектов изменяются в процессе изменения конфигурации уже работающей системы. Изменения параметров миграции для каждого из объектов производится независимо от других. То есть, Конфигуратор не отслеживает ссылки между объектами при настройке параметров миграции. Таким образом, при определенных вариантах настройки параметров миграции у некоторых объектов могут появиться ссылки, указывающие "никуда". Ответственность за сохранение ссылочной целостности в распределенных ИБ возлагается на лицо, занимающееся конфигурированием системы. Общим правилом настройки параметров миграции является определение области миграции для конкретного вида объектов равной более широкой, чем область миграции ссылающихся на него объектов. Например, для справочника область миграции должна быть определена не уже, чем области миграции документов и справочников, в которых есть реквизиты типа "справочник" данного вида. Если, например, измерение регистра имеет тип "справочник" данного вида, то область миграции справочника должна покрывать области миграции всех документов, которые могут записать движения данного регистра.
При изменении параметров миграции того или иного объекта система старается привести имеющиеся данные в соответствие с новыми параметрами. Общим принципом здесь является то, что при изменении параметров миграции объекты никогда ни в каком узле распределенной ИБ не удаляются. Даже в том случае, если в соответствии с вновь установленными параметрами миграции их там быть не должно. Изменения производятся лишь в таблице регистрации изменений. Рассмотрим случаи изменения параметров миграции объектов подробнее.
Наиболее простой случай - это смена любого из вариантов области распространения на вариант "Место создания". В этом случае из таблицы регистрации изменений удаляются все записи по данному виду объектов. То есть все изменения объектов, еще не переданные в другие ИБ, не будут переданы. При этом, все объекты для которых данная ИБ не является местом создания, не будут удалены. Просто их изменения (как и изменения других объектов данного вида) не будут больше передаваться в другие ИБ.
Следующий случай - это смена области распространения "Место создания" на варианты "Все информационные базы" или "Место создания и центр". В этом случае в таблицу регистрации изменений заносятся записи для передачи всех объектов, для которых текущая ИБ является местом создания во все ИБ, в которые должны передаваться изменения в соответствии с вновь заданной настройкой. В случае, если такая смена производится для объектов, для которых место создания не определено (константы, календари, корректные проводки), то записи в таблицу регистрации изменений будут произведены только в центральной ИБ. Этими двумя вариантами и ограничиваются возможные случаи изменения параметров миграции для такого рода объектов. Все остальные случаи возможны только для тех объектов, для которых место создания можно определить.
При изменении области распространения объектов с "Место создания и центр" на "Все информационные базы", какие-либо действия предпринимаются только в центральной ИБ. В этом случае определяется список периферийных ИБ, попавших в список дополнительно включаемых в область распространения, но ранее в него не входивших. После этого производится обход всех объектов данного вида и для каждого из объектов в таблицу регистрации изменений вносятся записи для передачи состояния объекта в каждую из попавших в список периферийных ИБ, за исключением ИБ места создания объекта.
Последний и самый сложный случай - это изменение области распространения объектов с "Все информационные базы" на "Место создания и центр" или изменение списка дополнительных ИБ в варианте "Место создания и центр". Действия, производимые в данном случае различаются в зависимости от того, производятся они в центральной ИБ или в периферийной. В центральной ИБ для каждой из периферийных ИБ, не попавших в новый перечень дополнительно включаемых в область распространения, выполняется удаление из таблицы регистрации изменений записей соответствующих данному виду объектов, но только для тех объектов, для которых эта периферийная ИБ не является местом создания. Затем определяется список периферийных ИБ, попавших в список дополнительно включаемых в область распространения, но ранее в него не входивших. Естественно, что в случае, если предыдущим вариантом настройки области распространения было "Все информационные базы", то этот список окажется пустым. Затем, как и в предыдущем случае, производится обход всех объектов данного вида и для каждого из объектов в таблицу регистрации изменений вносятся записи для передачи объекта в каждую из попавших в список периферийных ИБ, за исключением ИБ места создания объекта.
Проблемы конфигурирования и администрирования
При разработке конфигурации для распределенной ИБ проявляется ряд объективно существующих проблем, которые решаются как средствами конфигурации, так и административными решениями.
Очевидной проблемой, которая уже упоминалась выше, является уникальная и последовательная нумерация документов и элементов справочников. Для организации уникальной нумерации используется механизм префиксов. Для его включения в конфигурацию, прежде всего, следует выработать некоторую дисциплину, зависимости префикса от ИБ, в которой создается объект. В простейшем случае это может быть собственно код ИБ. Однако часто префикс может автоматически определяться на каждой ИБ, но не являться ее кодом, так как он может участвовать в печатных формах документов и должен быть понятным для пользователей системы. Более сложной задачей является обеспечение сквозной нумерации объектов без префиксов в случае, когда такая нумерация регламентируется нормативными документами. Особенно сложным является обеспечение строго последовательной нумерации. Очевидно, что полного решения данной проблемы не может быть в принципе, так как объекты создаваемые динамически в независимых системах не могут иметь строгой сквозной нумерации. Отчасти данная проблема решается с помощью введения диапазонов номеров, выделяемых для каждой ИБ. Следует заметить, что номера документов и коды справочников не являются внутренними идентификаторами и их уникальность для системы не обязательна. Это значит, что поддержку уникальность номеров и кодов можно отключить для тех видов, объектов, для которых она не нужна. Кроме того, средствами конфигурации можно организовать перенумерацию объектов, например в центральной ИБ. Однако следует иметь ввиду, что эти изменения будут передаваться как и любые другие изменения, что может вызвать достаточно большой объем передаваемых между узлами данных.
Более сложной проблемой является ситуация, когда возникает необходимость использования некоторого нового объекта в двух и более узлах одновременно, до осуществления передачи данных. Например, новый товар должен быть введен и на центральной ИБ и на периферийной. Важно понимать, что созданный ведущий объект системы 1С:Предприятие обладает некоторой сущностью - внутренним идентификатором, который уникален во всей распределенной системе. То есть один и тот же объект не может быть введен в двух узлах. Даже при полном соответствии кодов, номеров и всех данных это будут два разных объекта. Такой принцип необходим для четкой работы системы со всех точек зрения.
Заметим, что возможные варианты ввода двух объектов и затем автоматической замены на центральной ИБ всех ссылок на один из объектов, достаточно сложны в реализации и весьма ненадежны.
Поэтому, на наш взгляд, решение проблемы должно лежать в области администрирования системы. Технология работы пользователей должна быть построена таким образом, чтобы ввод объекта производился на одном узле.
В отдельных случаях может использоваться следующее решение. В справочник заранее вносится некоторое количество новых элементов со специальными кодами или в специальную группу. При появлении необходимости ввода нового товара реально не вводится новый элемент, а изменяется один этих элементов. При этом административными силами должно быть обеспечено идентичное изменение одного и того же "зарезервированного" объекта в тех узлах распределенной ИБ, в которой он должен быть использован до обмена данными. При обмене данными сами реквизиты элемента будут системой синхронизированы, а ссылки в других объектах, разумеется будут идентичными, так как использовался один и тот же объект.
В любых случаях следует учитывать, что раздельный ввод и использование объектов потребует от пользователей правильного ввода данных. Так, например, при вводе нового товара в двух узлах с разными ценами могут иметь место серьезные ошибки в оформлении документов.
Еще одна проблема, с которой приходится сталкиваться при конфигурировании распределенной ИБ, это правильное поддержание механизмов учета компонент при неполной миграции объектов. Следует учитывать, что итоги оперативного и бухгалтерского учета не являются самостоятельными объектами. Они не переносятся, а рассчитываются на основании перенесенных движений регистров и проводок. Движения регистров и проводки переносятся соответственно только вместе с документами. Таким образом, для правильного состояния итогов на некоторой ИБ, на нее должны переноситься все документы, осуществляющие движения регистров или записывающие проводки влияющие на эти итоги. С другой стороны, это не означает, что переноситься должны все документы, записывающие движения конкретного регистра и проводки. Например, если на периферийной ИБ вводятся документы, выполняющие движения по одному складу, и итоги регистра учета товарного запаса в данной ИБ нужны только по данному складу, то, разумеется, в данном узле будет достаточно наличия всех документов выполняющих движения регистров по данному складу. Это достигается установкой параметра миграции "Место создания и центр".
Часто программисту приходится сталкиваться с задачей написания приложения, работающего в фоновом режиме и не нуждающегося в месте на Панели задач. Если вы посмотрите на правый нижний угол рабочего стола windows, то наверняка найдете там приложения, для которых эта проблема решена: часы, переключатель раскладок клавиатуры, регулятор громкости и т. п. Ясно, что, как бы вы не увеличивали и не уменьшали формы своего приложения, попасть туда обычным путем не удастся. Способ для этого предоставляет shell api.
Те картинки, которые находятся на system tray — это действительно просто картинки, а не свернутые окна. Они управляются и располагаются панелью system tray. Она же берет на себя еще две функции: показ подсказки для каждого из значков и оповещение приложения, создавшего значок, обо всех перемещениях мыши над ним.
Весь api system tray состоит из 1 (одной) функции:
Код:
Параметр dwmessage определяет одну из операций: nim_add означает добавление значка в область, nim_delete — удаление, nim_modify — изменение.
Ход операции зависит от того, какие поля структуры tnotifyicondata будут заполнены.
Обязательным для заполнения является поле cbsize — там содержится размер структуры. Поле wnd должно содержать дескриптор окна, которое будет оповещаться о событиях, связанных со значком.
Идентификатор сообщения windows, которое вы хотите получать от системы о перемещениях мыши над значком, запишите в поле ucallbackmessage. Если вы хотите, чтобы при этих перемещениях над вашим значком показывалась подсказка, то задайте ее текст в поле sztip. В поле uid задается номер значка — каждое приложение может поместить на system tray сколько угодно значков. Дальнейшие операции вы будете производить, задавая этот номер. Дескриптор помещаемого значка должен быть задан в поле hicon. Здесь вы можете задать значок, связанный с вашим приложением, или загрузить свой — из ресурсов.
Примечание
Изменить главный значок приложения можно в диалоговом окне project/ options на странице application. Он будет доступен через свойство application.icon. Тут же можно отредактировать и строку для подсказки — свойство application.title.
Наконец, в поле uflags вы должны сообщить системе, что именно вы от нее хотите, или, другими словами, какие из полей hicon, ucallbackmessage и sztip вы на самом деле заполнили. В этом поле предусмотрена комбинация трех флагов: nif_icon, nif_message и nif_tip. Вы можете заполнить, скажем, поле sztip, но если вы при этом не установили флаг nif_tip, созданный вами значок не будет иметь строки с подсказкой.
Два приведенных ниже метода иллюстрируют сказанное. Первый из них создает значок на system tray, а второй — уничтожает его.
Код:
Примечание
he забывайте уничтожать созданные вами значки на system tray. Это не делается автоматически даже при закрытии приложения. Значок будет удален только после перезагрузки системы.
Сообщение, задаваемое в поле ucallbackmessage, по сути дела является единственной ниточкой, связывающей вас со значком после его создания. Оно объединяет в себе несколько сообщений. Когда к вам пришло такое сообщение (в примере, рассмотренном выше, оно имеет идентификатор wm_mytraynotify), поля в переданной в обработчик структуре типа tmessage распределены так. Параметр wparam содержит номер значка (тот самый, что задавался в поле uid при его создании), а параметр lparam — идентификатор сообщения от мыши, вроде wm_mousemove, wm_lbuttondown и т. п. К сожалению, остальная информация из этих сообщений теряется.
Координаты мыши в момент события придется узнать, вызвав функцию api getcursorpos:
Код:
Обратите внимание, что при показе всплывающего меню недостаточно просто вызвать метод popup. При этом нужно вынести главную форму приложения на передний план, в противном случае она не получит сообщений от меню.
Теперь решим еще две задачи. Во-первых, как сделать, чтобы приложение минимизировалось не на Панель задач (taskbar), а на system tray? И более того — как сразу запустить его в минимизированном виде, а показывать главную форму только по наступлении определенного события (приходу почты, наступлению определенного времени и т. п.).
Ответ на первый вопрос очевиден. Если минимизировать не только окно главной формы приложения (application.mainform.handle), но и окно приложения (application.handle), то приложение полностью исчезнет "с экранов радаров". В этот самый момент нужно создать значок на панели system tray. В его всплывающем меню должен быть пункт, при выборе которого оба окна восстанавливаются, а значок удаляется.
Чтобы приложение запустилось сразу в минимизированном виде и без главной формы, следует к вышесказанному добавить установку свойства application.showmainform в значение false. Здесь возникает одна сложность — если главная форма создавалась в невидимом состоянии, ее компоненты будут также созданы невидимыми. Поэтому при первом ее показе установим их свойство visible в значение true. Чтобы не повторять это дважды, установим флаг — глобальную переменную shownonce:
Код:
Теперь у вас в руках полноценный набор средств для работы с панелью system tray.
В заключение необходимо добавить, что все описанное реализуется не в операционной системе, а в оболочке ОС — Проводнике (explorer). В принципе, и windows nt 4/2000, и windows 95/98 допускают замену оболочки ОС на другие, например dashboard или lightstep. Там функции панели system tray могут быть не реализованы или реализованы через другие api. Впрочем, случаи замены оболочки достаточно редки.
Я очень часто встречаю вопрос типа "Как удалить определенную строку из файла?". Народ совсем не хочет шевелиться, ведь так легко зайти на любой крупный форум по PHP, и в сроке поиска написать что-то типа "Удаление строк из файла". Пятерка результатов гарантирована. Итак, в первой части статьи мы как раз рассмотрим способ удаления определенной строки из текстового файла.
Для начала было бы совсем не плохо создать текстовый файл. Назовём его file.txt, который будет состоять из строк, которые мы будем удалять:
Затем создаём что-нибудь типа file.php, занимающий около 11 строк!
Сначала определимся, что для удаления определенной строки нам нужен её номер. Его мы будем передавать с идентификатором id: file.php?id=2 (удалим строку под номером ТРИ, так как исчисления элементов в массиве ведётся с нуля, но позже мы это сгладим).
- функция file() считывает весь файл в массив (каждая строка - это его элемент);
- $id-вычитает один из нашего идентификатора, так что 2 становится 2, а 3 - 3;
- unset($file[$i]) удаляет или обнуляет элемент массива (но только из памяти, т. е. виртуально:);
- implode() объединяет массив в одну строку. Это очень важно, так как если бы это опустили, наш файл бы похудел до бесполезной записи Array
Перед работой через протокол POP3 сервер прослушивает порт 110. Когда клиент хочет использовать этот протокол, он должен создать TCP соединение с сервером. Когда соединение установлено, сервер отправляет приглашение. Затем клиент и POP3 сервер обмениваются информацией пока соединение не будет закрыто или прервано.
Команды POP3 состоят из ключевых слов, за некоторыми следует один или более аргументов. Все команды заканчиваются парой CRLF (в Visual Basic константа vbCrLf). Ключевые слова и аргументы состоят из печатаемых ASCII символов. Ключевое слово и аргументы разделены одиночным пробелом. Ключевое слово состоит от 3-х до 4-х символов, а аргумент может быть длиной до 40-ка символов.
Ответы в POP3 состоят из индикатора состояния и ключевого слова, за которым может следовать дополнительная информация. Ответ заканчивается парой CRLF. Существует только два индикатора состояния: "+OK" - положительный и "-ERR" - отрицательный.
Ответы на некоторые команды могут состоять из нескольких строк. В этих случаях каждая строка разделена парой CRLF, а конец ответа заканчивается ASCII символом 46 (".") и парой CRLF.
POP3 сессия состоит из нескольких режимов. Как только соединение с сервером было установлено и сервер отправил приглашение, то сессия переходит в режим AUTHORIZATION (Авторизация). В этом режиме клиент должен идентифицировать себя на сервере. После успешной идентификации сессия переходит в режим TRANSACTION (Передача). В этом режиме клиент запрашивает сервер выполнить определённые команды. Когда клиент отправляет команду QUIT, сессия переходит в режим UPDATE. В этом режиме POP3 сервер освобождает все занятые ресурсы и завершает работу. После этого TCP соединение закрывается.
У POP3 сервера может быть INACTIVITY AUTOLOGOUT таймер. Этот таймер должен быт, по крайней мере, с интервалом 10 минут. Это значит, что если клиент и сервер не взаимодействуют друг с другом, сервер автоматически прерывает соединение и при этом не переходит в режим UPDATE.
Авторизация в протоколе POP3
Как только будет установлено TCP соединение с POP3 сервером, он отправляет приглашение, заканчивающееся парой CRLF, например:
Теперь POP3 сессия находится в режиме AUTHORIZATION. Клиент должен идентифицировать себя на сервере, используя команды USER и PASS. Сначала надо отправить команду USER, после которой в качестве аргумента следует имя пользователя. Если сервер отвечает положительно, то теперь необходимо отправить команду PASS, за которой следует пароль. Если после отправки команды USER или PASS сервер отвечает негативно, то можно поробовать авторизироваться снова или выйти из сесси с помощью команды QUIT. После успешной авторизации сервер открывает и блокирует maildrop (почтовый ящик). В ответе на команду PASS сервер сообщает сколько сообщений находится в почтовом ящике и передаёт их общий размер. Теперь сессия находится в режиме TRANSACTION. Подведём итоги с командами:
Команда: USER [имя]
Аргументы: [имя] - строка, указывающая имя почтового ящика
Описание: Передаёт серверу имя пользователя.
Возможные ответы:
* +OK name is a valid mailbox
* -ERR never heard of mailbox name
Примеры:
C: USER MonstrVB
S: +OK MonstrVB is a real hoopy frood
...
C: USER MonstrVB
S: -ERR sorry, no mailbox for frated here
* +OK maildrop locked and ready
* -ERR invalid password
* -ERR unable to lock maildrop
Примеры:
C: USER MonstrVB
S: +OK MonstrVB is a real hoopy frood
C: PASS mymail
S: +OK MonstrVB's maildrop has 2 messages (320 octets)
...
C: USER MonstrVB
S: +OK MonstrVB is a real hoopy frood
C: PASS mymail
S: -ERR maildrop already locked
Команда: QUIT
Аргументы: нет
Описание: Сервер завершает POP3 сессию и переходит в режим UPDATE. Возможные ответы:
* +OK
Примеры:
C: QUIT
S: +OK dewey POP3 server signing off
Основные команды (Transaction) протоколе в POP3
После успешной идентификации пользователя на сервере POP3 сессия переходит в режим TRANSACTION, где пользователь может передавать ниже следующие команды. После каждой из таких команд следут ответ сервера. Вот доступные команды в этом режиме:
Команда: STAT
Аргументы: нет
Описание: В ответ на вызов команды сервер выдаёт положительный ответ "+OK", за которым следует количество сообщений в почтовом ящике и их общий размер в символах. Сообщения, которые помечены для удаления не учитываются в ответе сервера.
Возможные ответы:
* +OK n s
Примеры:
C: STAT
S: +OK 2 320
Команда: LIST [сообщение]
Аргументы: [сообщение] - номер сообщения (необязательный аргумент)
Описание: Если был передан аргумент, то сервер выдаёт информацию о указанном сообщении. Если аргумент не был передан, то сервер выдаёт информацию о всех сообщениях, находящихся в почтовом ящике. Сообщения, помеченные для удаления не перечисляются.
Возможные ответы:
* +OK scan listing follows
* -ERR no such message
Примеры:
C: LIST
S: +OK 2 messages (320 octets)
S: 1 120
S: 2 200
S: .
...
C: LIST 2
S: +OK 2 200
...
C: LIST 3
S: -ERR no such message, only 2 messages in maildrop
Команда:RETR [сообщение]
Аргументы: [сообщение] - номер сообщения
Описание: После положительного ответа сервер передаёт содержание сообщения.
Возможные ответы:
* +OK message follows
* -ERR no such message
Примеры:
C: RETR 1
S: +OK 120 octets
S:
S: .
Команда: DELE [ообщение]
Аргументы: [ообщение] - номер сообщения
Описание: POP3 сервер помечает указанное сообщение как удалённое, но не удалет его, пока сессия не перейдёт в редим UPDATE.
Возможные ответы:
* +OK message deleted
* -ERR no such message
Примеры:
C: DELE 1
S: +OK message 1 deleted
...
C: DELE 2
S: -ERR message 2 already deleted
Команда: NOOP
Аргументы: нет
Описание: POP3 сервер ничего не делает и вседа отвечает полжительно.
Возможные ответы:
* +OK
Примеры:
C: NOOP
S: +OK
Команда: RSET
Аргументы: нет
Описание: Если какие - то сообщения были помечены для удаления, то с них снимается эта метка.
Возможные ответы:
* +OK
Примеры:
C: RSET
S: +OK maildrop has 2 messages (320 octets)
Обновление
Когда клиент передаёт команду QUIT в режиме TRANSACTION, то сессия переходит в режим UPDATE. В этом режиме сервер удаляет все сообщения, помеченные для удаления. После этого TCP соединение закрывается.
Дополнительные POP3 команды
Следующие дополнительные команды дают вам большую свободу при работе с сообщениями: Команда: TOP [сообщение] [n] Аргументы: [сообщение] - номер сообщения [n] - положительное число (обязательный аргумент) Описание: Если ответ сервера положительный, то после него он передаёт заголовки сообщения и указанное кол - во строк из тела сообщения. Возможные ответы: +OK top of message follows -ERR no such message Примеры: C: TOP 1 10 S: +OK S: <здесь POP3 сервер передаёт заголовки первого сообщения и первые 10-ть строк из тела сообщения.> S: . ... C: TOP 100 3 S: -ERR no such message Команда: UIDL [сообщение] Аргументы: [сообщение] - номер сообщения (необязательный аргумент). Описание: Если был указан номер сообщения, то сервер выдаёт уникальный идентификатор для этого сообщения. Если аргумент не был передан, то идентификаторы перечисляются для всех сообщений, кроме помеченных для удаления.
Возможные ответы: +OK unique-id listing follows -ERR no such message
Примеры: C: UIDL S: +OK S: 1 whqtswO00WBw418f9t5JxYwZ S: 2 QhdPYR:00WBw1Ph7x7 S: . ... C: UIDL 2 S: +OK 2 QhdPYR:00WBw1Ph7x7 ... C: UIDL 3 S: -ERR no such message, only 2 messages in maildrop
Итак, что нам понадобится. В первую очередь - Delphi 5-7 (у меня стоит 7-я версия, и весь код тестировался именно в этой версии). Это вызвано тем, что компонент TWebBrowser впервые "прописался" на вкладке Internet именно в 5-й версии (в 4-й его надо было устанавливать как компонент ActiveX).
Сначала нам надо перевести WebBrowser в режим редактирования. Для этого у каждого документа (согласно объектной модели это document) существует свойство DesignMode. Если установить его в 'On', то наша компонента автоматически переключается в режим редактирования, а если установить его в 'Off', то компонент вернется в режим просмотра.
Проверим это! Создадим новую форму, разместим на ней компоненту TWebBrowser и несколько компонент TSpeedButton. Затем напишем такой код:
Код:
Теперь по порядку о том, что мы написали. В событии OnCreate формы мы загружаем в браузер простую страницу (напомню, что протокол About позволяет загружать в браузер HTML строку). Это необходимо для того, чтобы в последующем мы могли обращаться к документу. Сразу после этого будет вызван обработчик события OnDocumentComplete. Но пока еще ничего не произошло. Внимательный читатель мог обратить внимание, что для перевода браузера в режим редактирования надо нажать кнопку 1. Editor - это экземпляр нашего документа (document). Его свойство DesignMode устанавливается в 'On'. Теперь наш редактор практически готов. Он уже умеет править текст, копировать/вырезать/вставлять текст и картинки, делать текст жирным/подчеркнутым/наклонным. Для этого есть соответствующие комбинации клавиш.
Ctrl + C Копировать
Ctrl + X Вырезать
Ctrl + V Вставить
Ctrl + B Жирный текст
Ctrl + I Наклонный текст
Ctrl + U Подчеркнутый текст
Ctrl + Z Отменить
Ctrl + Y Повторить
Ctrl + K Гиперссылка
Ctrl + F Найти
Ctrl + A Выделить всё
Ctrl + Left-Click Выделить блок
"Это, конечно, хорошо, что есть горячие клавиши, но мне не хотелось бы все их запоминать" - можете сказать вы. Хорошо. Тогда давайте разберем, как из Delphi заставить WebBrowser выполнять все эти действия. Для этого есть метод Command интерфейса IHTMLTxtRange (он описан в модуле MSHTML_TLB). Рассмотрим простой пример.
Код:
Сначала в этой процедуре создается объект Range. После этого вызывается метод Command:
Код:
cmdID – это строка идентификатор команды (в нашем примере 'bold' заставляет редактор переключаться между жирным и обычным начертанием текста); полный список команд смотри в приложении.
ShowUI – Show User Interface - показывать интерфейс пользователя (если таковой имеется, как правило это различные диалоговые окна). Если параметр равен False, то команда выполняется без предупреждения.
value – содержит дополнительную информацию в зависимости от команды.
Несколько слов об объекте Range. Помимо уже знакомого нам Command этот объект обладает еще рядом свойств и методов, некоторые из которых сейчас рассмотрим.
Text - Содержит текст выделения (без тегов HTML)
HTMLText - Полный текст выделения
Код:
procedure - Перемещает начальную позицию выделения на count символов вправо (если count<0, то влево), unit_-единицы измерения смещения (чаще всего используется 'character': 1 символ). При этом конечная позиция не смещается.
Код:
То же самое, только для конечной позиции выделения.
Код:
Вставляет HTML-строку
Код:
Отображает помощь по команде, указанной в cmdID
Пожалуй, на сегодня всё. Об остальных объектах (картинки, таблицы, элементы управления) поговорим в другой раз. Будут вопросы - пишите: [email=samum2000@mail15.com?subject=Question about visualhtml part1]samum2000@mail15.com[/email].
Приложение. Доступные команды:
BackColor - Устанавливает или получает цвет фона текущего выделения. Value должно содержать имя цвета или его шеснадцитиричный RGB эквивалент (например, #FFCC00).
Bold - Переключает начертание текста текущего выделения между полужирным и нормальным.
Copy - Копирует выделение в буфер обмена
CreateBookmark - Получает имя якоря или создает его для текущего выделения. Value - строка, содержащая имя якоря.
CreateLink - Получает URL ссылки или создает новую ссылку. Параметр Value должен содержать URL.
Cut - Вырезает текущее выделение в буфер обмена.
Delete - Очищает текущее выделение (удаляет всё его содержимое).
Find - Находит текст, заданный в параметре Value в текущем выделении.
FontName - Устанавливает шрифт для текущего выделения. Value содержит описание этого шрифта (как в теге FONT).
FontSize - Устанавливает размер шрифта. Value - число от 1 до 7 включительно.
ForeColor - Устанавливает цвет текста. Value должно содержать имя цвета или его шеснадцитиричный RGB эквивалент (например, #FFCC00)
FormatBlock - Устанавливает или получает форматирование текущего блока. Value может содержать теги-описатели.
Indent - Увеличивает отступ выделенного текста на одну единицу приращения
InsertButton - Перезаписывает идентификатор кнопки вместо текущего выделения. Value - строка, содержащая идентификатор кнопки.
InsertFieldset - То же для поля ввода.
InsertHorizontalRule - То же для горизонтальной полосы.
InsertIFrame - То же для встроеных фреймов (IFRAME).
InsertImage - То же для изображений.
InsertInputButton - То же для кнопки.
InsertInputCheckbox - То же для чекбоксов (checkBox).
InsertInputFileUpload - То же для элемента выбора файла.
InsertInputHidden - То же для скрытого поля (hidden)
InsertInputImage - То же для изображения.
InsertInputPassword - То же для поля ввода пароля.
InsertInputRadio - То же для радио-кнопок (Radio)
InsertInputReset - То же для кнопки reset.
InsertInputSubmit - То же для кнопки Submit.
InsertInputText - То же для поля ввода текста.
InsertParagraph - Вставляет новый раздел (абзац).
InsertOrderedList - Переключает стиль текущего выделения между списком и простым текстом.
InsertUnorderedList - То же самое.
InsertSelectDropdown - Записывает элемент Drop-down вместо текущего выделения. Value должно содержать идентификатор элемента.
InsertTextArea - То же для элемента TextArea.
Italic - Переключает начертание текста текущего выделения между наклонным и обычным.
JustifyCenter - Устанавливает выравнивание по центру для всего блока, в котором расположено текущее выделение.
JustifyLeft - Устанавливает выравнивание по левому краю для всего блока, в котором расположено текущее выделение.
JustifyRight - Устанавливает выравнивание по правому краю для всего блока, в котором расположено текущее выделение.
Outdent - Уменьшает отступ для всего блока, в котором расположено выделение, на одну единицу.
OverWrite - Переключается между режимами вставки текста и замены текста при вводе. Value: true - замена, false - вставка.
Paste - Вставляет текст из буфера обмена вместо текущего выделения.
Refresh - Обновляет текущий документ.
RemoveFormat - Удаляет из текущего фрагмента все теги форматирования
SelectAll - Выделяет все содержимое документа.
UnBookmark - Удаляет все закладки из текущего выделения.
Underline - Переключает начертание текста текущего выделения между подчеркнутым и обычным.
Unlink - Удаляет все гиперссылки из текущего выделенного фрагмента.
Unselect - Снимает выделение.
В этой статье описываются полезные функции и процедуры, помогающие эффективно работать с различными типами данных в системе "1С:Предприятие 7.7".
* Обработка значений
* Форматирование
* Список значений
* Таблица значений
* Таблица
* Период и дата
* Календари и праздники
* Справочники
* Документы
* Предопределённые функции
* Налоговый учёт
Обработка значений в 1С
Форматирование данных в 1С
Список значений в 1С
Таблица значений в 1С
Таблица или печатная форма в 1С
Периоды и даты в 1С
Календари и праздники в 1С
Справочники в 1С
Документы в 1С
Предопределённые функции и процедуры в 1С
Налоговый учёт и первое событие в 1С
Резюме
В статье описаны функции и процедуры, используемые в программе "1С:Предприятие 7.7" для работы со справочниками, документами, списками значений, таблицами значений и с прочими агрегатными типами данных. Образцы практического применения описанных средств Вы сможете найти в статьях "Отчёты для 1С" и "Обработки для 1С".
Сеть всегда объединяет несколько абонентов, каждый из которых имеет право передавать свои пакеты. Но, как уже отмечалось, по одному кабелю одновременно передавать два (или более) пакета нельзя, иначе может возникнуть конфликт (коллизия), который приведет к искажению либо потере обоих пакетов (или всех пакетов, участвующих в конфликте). Значит, надо каким-то образом установить очередность доступа к сети (захвата сети) всеми абонентами, желающими передавать. Это относится, прежде всего, к сетям с топологиями шина и кольцо. Точно так же при топологии звезда необходимо установить очередность передачи пакетов периферийными абонентами, иначе центральный абонент просто не сможет справиться с их обработкой.
В сети обязательно применяется тот или иной метод управления обменом (метод доступа, метод арбитража), разрешающий или предотвращающий конфликты между абонентами. От эффективности работы выбранного метода управления обменом зависит очень многое: скорость обмена информацией между компьютерами, нагрузочная способность сети (способность работать с различными интенсивностями обмена), время реакции сети на внешние события и т.д. Метод управления – это один из важнейших параметров сети.
Тип метода управления обменом во многом определяется особенностями топологии сети. Но в то же время он не привязан жестко к топологии, как нередко принято считать.
Методы управления обменом в локальных сетях делятся на две группы:
* Централизованные методы, в которых все управление обменом сосредоточено в одном месте. Недостатки таких методов: неустойчивость к отказам центра, малая гибкость управления (центр обычно не может оперативно реагировать на все события в сети). Достоинство централизованных методов – отсутствие конфликтов, так как центр всегда предоставляет право на передачу только одному абоненту, и ему не с кем конфликтовать.
* Децентрализованные методы, в которых отсутствует центр управления. Всеми вопросами управления, в том числе предотвращением, обнаружением и разрешением конфликтов, занимаются все абоненты сети. Главные достоинства децентрализованных методов: высокая устойчивость к отказам и большая гибкость. Однако в данном случае возможны конфликты, которые надо разрешать.
Существует и другое деление методов управления обменом, относящееся, главным образом, к децентрализованным методам:
* Детерминированные методы определяют четкие правила, по которым чередуются захватывающие сеть абоненты. Абоненты имеют определенную систему приоритетов, причем приоритеты эти различны для всех абонентов. При этом, как правило, конфликты полностью исключены (или маловероятны), но некоторые абоненты могут дожидаться своей очереди на передачу слишком долго. К детерминированным методам относится, например, маркерный доступ (сети Token-Ring, FDDI), при котором право передачи передается по эстафете от абонента к абоненту.
* Случайные методы подразумевают случайное чередование передающих абонентов. При этом возможность конфликтов подразумевается, но предлагаются способы их разрешения. Случайные методы значительно хуже (по сравнению с детерминированными) работают при больших информационных потоках в сети (при большом трафике сети) и не гарантируют абоненту величину времени доступа. В то же время они обычно более устойчивы к отказам сетевого оборудования и более эффективно используют сеть при малой интенсивности обмена. Пример случайного метода – CSMA/CD (сеть Ethernet).
Для трех основных топологий характерны три наиболее типичных метода управления обменом.
Управление обменом в сети с топологией звезда
Для топологии звезда лучше всего подходит централизованный метод управления. Это связано с тем, что все информационные потоки проходят через центр, и именно этому центру логично доверить управление обменом в сети. Причем не так важно, что находится в центре звезды: компьютер (центральный абонент), как на рис. 1.6, или же специальный концентратор, управляющий обменом, но сам не участвующий в нем. В данном случае речь идет уже не о пассивной звезде (рис. 1.11), а о некой промежуточной ситуации, когда центр не является полноценным абонентом, но управляет обменом. Это, к примеру, реализовано в сети 100VG-AnyLAN.
Самый простейший централизованный метод состоит в следующем.
Периферийные абоненты, желающие передать свой пакет (или, как еще говорят, имеющие заявки на передачу), посылают центру свои запросы (управляющие пакеты или специальные сигналы). Центр же предоставляет им право передачи пакета в порядке очередности, например, по их физическому расположению в звезде по часовой стрелке. После окончания передачи пакета каким-то абонентом право передавать получит следующий по порядку (по часовой стрелке) абонент, имеющий заявку на передачу (рис. 4.8). Например, если передает второй абонент, то после него имеет право на передачу третий. Если же третьему абоненту не надо передавать, то право на передачу переходит к четвертому и т.д.
Централизованный метод управления обменом в сети с топологией звезда
Рис. 4.8. Централизованный метод управления обменом в сети с топологией звезда
В этом случае говорят, что абоненты имеют географические приоритеты (по их физическому расположению). В каждый конкретный момент наивысшим приоритетом обладает следующий по порядку абонент, но в пределах полного цикла опроса ни один из абонентов не имеет никаких преимуществ перед другими. Никому не придется ждать своей очереди слишком долго. Максимальная величина времени доступа для любого абонента в этом случае будет равна суммарному времени передачи пакетов всех абонентов сети кроме данного. Для топологии, показанной на рис. 4.8, она составит четыре длительности пакета. Никаких столкновений пакетов при этом методе в принципе быть не может, так как все решения о доступе принимаются в одном месте.
Рассмотренный метод управления можно назвать методом с пассивным центром, так как центр пассивно прослушивает всех абонентов. Возможен и другой принцип реализации централизованного управления (его можно назвать методом с активным центром).
В этом случае центр посылает запросы о готовности передавать (управляющие пакеты или специальные сигналы) по очереди всем периферийным абонентам. Тот периферийный абонент, который хочет передавать (первый из опрошенных) посылает ответ (или же сразу начинает свою передачу). В дальнейшем центр проводит сеанс обмена именно с ним. После окончания этого сеанса центральный абонент продолжает опрос периферийных абонентов по кругу (как на рис. 4.8). Если желает передавать центральный абонент, он передает вне очереди.
Как в первом, так и во втором случае никаких конфликтов быть не может (решение принимает единый центр, которому не с кем конфликтовать). Если все абоненты активны, и заявки на передачу поступают интенсивно, то все они будут передавать строго по очереди. Но центр должен быть исключительно надежен, иначе будет парализован весь обмен. Механизм управления не слишком гибок, так как центр работает по жестко заданному алгоритму. К тому же скорость управления невысока. Ведь даже в случае, когда передает только один абонент, ему все равно приходится ждать после каждого переданного пакета, пока центр опросит всех остальных абонентов.
Как правило, централизованные методы управления применяются в небольших сетях (с числом абонентов не более чем несколько десятков). В случае больших сетей нагрузка по управлению обменом на центр существенно возрастает.
Управление обменом в сети с топологией шина
При топологии шина также возможно централизованное управление. При этом один из абонентов ("центральный") посылает по шине всем остальным ("периферийным") запросы (управляющие пакеты), выясняя, кто из них хочет передать, затем разрешает передачу одному из абонентов. Абонент, получивший право на передачу, по той же шине передает свой информационный пакет тому абоненту, которому хочет. А после окончания передачи передававший абонент все по той же шине сообщает "центру", что он закончил передачу (управляющим пакетом), и "центр" снова начинает опрос (рис. 4.9).
Централизованное управление в сети с топологией шина
Рис. 4.9. Централизованное управление в сети с топологией шина
Преимущества и недостатки такого управления – те же самые, что и в случае централизованно управляемой звезды. Единственное отличие состоит в том, что центр здесь не пересылает информацию от одного абонента к другому, как в топологии активная звезда, а только управляет обменом.
Гораздо чаще в шине используется децентрализованное случайное управление, так как сетевые адаптеры всех абонентов в данном случае одинаковы, и именно этот метод наиболее органично подходит шине. При выборе децентрализованного управления все абоненты имеют равные права доступа к сети, то есть особенности топологии совпадают с особенностями метода управления. Решение о том, когда можно передавать свой пакет, принимается каждым абонентом на месте, исходя только из анализа состояния сети. В данном случае возникает конкуренция между абонентами за захват сети, и, следовательно, возможны конфликты между ними и искажения передаваемой информации из-за наложения пакетов.
Существует множество алгоритмов доступа или, как еще говорят, сценариев доступа, порой очень сложных. Их выбор зависит от скорости передачи в сети, длины шины, загруженности сети (интенсивности обмена или трафика сети), используемого кода передачи.
Иногда для управления доступом к шине применяется дополнительная линия связи, что позволяет упростить аппаратуру контроллеров и методы доступа, но заметно увеличивает стоимость сети за счет удвоения длины кабеля и количества приемопередатчиков. Поэтому данное решение не получило широкого распространения.
Суть всех случайных методов управления обменом довольно проста.
Если сеть свободна (то есть никто не передает своих пакетов), то абонент, желающий передавать, сразу начинает свою передачу. Время доступа в этом случае равно нулю.
Если же в момент возникновения у абонента заявки на передачу сеть занята, то абонент, желающий передавать, ждет освобождения сети. В противном случае исказятся и пропадут оба пакета. После освобождения сети абонент, желающий передавать, начинает свою передачу.
Возникновение конфликтных ситуаций (столкновений пакетов, коллизий), в результате которых передаваемая информация искажается, возможно в двух случаях.
* При одновременном начале передачи двумя или более абонентами, когда сеть свободна (рис. 4.10). Это ситуация довольно редкая, но все-таки вполне возможная.
* При одновременном начале передачи двумя или более абонентами сразу после освобождения сети (рис. 4.11). Это ситуация наиболее типична, так как за время передачи пакета одним абонентом вполне может возникнуть несколько новых заявок на передачу у других абонентов.
Существующие случайные методы управления обменом (арбитража) различаются тем, как они предотвращают возможные конфликты или же разрешают уже возникшие. Ни один конфликт не должен нарушать обмен, все абоненты должны, в конце концов, передать свои пакеты.
В процессе развития локальных сетей было разработано несколько разновидностей случайных методов управления обменом.
Коллизии в случае начала передачи при свободной сети
Рис. 4.10. Коллизии в случае начала передачи при свободной сети
Коллизии в случае начала передачи после освобождения сети
Рис. 4.11. Коллизии в случае начала передачи после освобождения сети
Например, был предложен метод, при котором не все передающие абоненты распознают коллизию, а только те, которые имеют меньшие приоритеты. Абонент с максимальным приоритетом из всех, начавших передачу, закончит передачу своего пакета без ошибок. Остальные, обнаружив коллизию, прекратят свою передачу и будут ждать освобождения сети для новой попытки. Для контроля коллизии каждый передающий абонент производит побитное сравнение передаваемой им в сеть информации и данных, присутствующих в сети. Побеждает тот абонент, заголовок пакета которого дольше других не искажается от коллизии. Этот метод, называемый децентрализованным кодовым приоритетным методом, отличается низким быстродействием и сложностью реализации.
При другом методе управления обменом каждый абонент начинает свою передачу после освобождения сети не сразу, а, выдержав свою, строго индивидуальную задержку, что предотвращает коллизии после освобождения сети и тем самым сводит к минимуму общее количество коллизий. Максимальным приоритетом в этом случае будет обладать абонент с минимальной задержкой. Столкновения пакетов возможны только тогда, когда два и более абонентов захотели передавать одновременно при свободной сети. Этот метод, называемый децентрализованным временным приоритетным методом, хорошо работает только в небольших сетях, так как каждому абоненту нужно обеспечить свою индивидуальную задержку.
В обоих случаях имеется система приоритетов, все же данные методы относятся к случайным, так как исход конкуренции невозможно предсказать. Случайные приоритетные методы ставят абонентов в неравные условия при большой интенсивности обмена по сети, так как высокоприоритетные абоненты могут надолго заблокировать сеть для низкоприоритетных абонентов.
[pagebreak]
Чаще всего система приоритетов в методе управления обменом в шине отсутствует полностью. Именно так работает наиболее распространенный стандартный метод управления обменом CSMA/CD (Carrier Sense Multiple Access with Collision Detection – множественный доступ с контролем несущей и обнаружением коллизий), используемый в сети Ethernet. Его главное достоинство в том, что все абоненты полностью равноправны, и ни один из них не может надолго заблокировать обмен другому (как в случае наличия приоритетов). В этом методе коллизии не предотвращаются, а разрешаются.
Суть метода состоит в том, что абонент начинает передавать сразу, как только он выяснит, что сеть свободна. Если возникают коллизии, то они обнаруживаются всеми передающими абонентами. После чего все абоненты прекращают свою передачу и возобновляют попытку начать новую передачу пакета через временной интервал, длительность которого выбирается случайным образом. Поэтому повторные коллизии маловероятны.
Еще один распространенный метод случайного доступа – CSMA/CA (Carrier Sense Multiple Access with Collision Avoidance – множественный доступ с контролем несущей и избежанием коллизий) применяющийся, например, в сети Apple LocalTalk. Абонент, желающий передавать и обнаруживший освобождение сети, передает сначала короткий управляющий пакет запроса на передачу. Затем он заданное время ждет ответного короткого управляющего пакета подтверждения запроса от абонента-приемника. Если ответа нет, передача откладывается. Если ответ получен, передается пакет. Коллизии полностью не устраняются, но в основном сталкиваются управляющие пакеты. Столкновения информационных пакетов выявляются на более высоких уровнях протокола.
Подобные методы будут хорошо работать только при не слишком большой интенсивности обмена по сети. Считается, что приемлемое качество связи обеспечивается при нагрузке не выше 30—40% (то есть когда сеть занята передачей информации примерно на 30—40% всего времени). При большей нагрузке повторные столкновения учащаются настолько, что наступает так называемый коллапс или крах сети, представляющий собой резкое падение ее производительности.
Недостаток всех случайных методов состоит еще и в том, что они не гарантируют величину времени доступа к сети, которая зависит не только от выбора задержки между попытками передачи, но и от общей загруженности сети. Поэтому, например, в сетях, выполняющих задачи управления оборудованием (на производстве, в научных лабораториях), где требуется быстрая реакция на внешние события, сети со случайными методами управления используются довольно редко.
При любом случайном методе управления обменом, использующем детектирование коллизии (в частности, при CSMA/CD), возникает вопрос о том, какой должна быть минимальная длительность пакета, чтобы коллизию обнаружили все начавшие передавать абоненты. Ведь сигнал по любой физической среде распространяется не мгновенно, и при больших размерах сети (диаметре сети) задержка распространения может составлять десятки и сотни микросекунд. Кроме того, информацию об одновременно происходящих событиях разные абоненты получают не в одно время. С тем чтобы рассчитать минимальную длительность пакета, следует обратиться к рис. 4.12.
Расчет минимальной длительности пакета
Рис. 4.12. Расчет минимальной длительности пакета
Пусть L – полная длина сети, V – скорость распространения сигнала в используемом кабеле. Допустим, абонент 1 закончил свою передачу, а абоненты 2 и 3 захотели передавать во время передачи абонента 1 и ждали освобождения сети.
После освобождения сети абонент 2 начнет передавать сразу же, так как он расположен рядом с абонентом 1. Абонент 3 после освобождения сети узнает об этом событии и начнет свою передачу через временной интервал прохождения сигнала по всей длине сети, то есть через время L/V. При этом пакет от абонента 3 дойдет до абонента 2 еще через временной интервал L/V после начала передачи абонентом 3 (обратный путь сигнала). К этому моменту передача пакета абонентом 2 не должна закончиться, иначе абонент 2 так и не узнает о столкновении пакетов (о коллизии), в результате чего будет передан неправильный пакет.
Получается, что минимально допустимая длительность пакета в сети должна составлять 2L/V, то есть равняться удвоенному времени распространения сигнала по полной длине сети (или по пути наибольшей длины в сети). Это время называется двойным или круговым временем задержки сигнала в сети или PDV (Path Delay Value). Этот же временной интервал можно рассматривать как универсальную меру одновременности любых событий в сети.
Стандартом на сеть задается как раз величина PDV, определяющая минимальную длину пакета, и из нее уже рассчитывается допустимая длина сети. Дело в том, что скорость распространения сигнала в сети для разных кабелей отличается. Кроме того, надо еще учитывать задержки сигнала в различных сетевых устройствах. Расчетам допустимых конфигураций сети Ethernet посвящена глава 10.
Отдельно следует остановиться на том, как сетевые адаптеры распознают коллизию в кабеле шины, то есть столкновение пакетов. Ведь простое побитное сравнение передаваемой абонентом информации с той, которая реально присутствует в сети, возможно только в случае самого простого кода NRZ, используемого довольно редко. При применении манчестерского кода, который обычно подразумевается в случае метода управления обменом CSMA/CD, требуется принципиально другой подход.
Как уже отмечалось, сигнал в манчестерском коде всегда имеет постоянную составляющую, равную половине размаха сигнала (если один из двух уровней сигнала нулевой). Однако в случае столкновения двух и более пакетов (при коллизии) это правило выполняться не будет. Постоянная составляющая суммарного сигнала в сети будет обязательно больше или меньше половины размаха (рис. 4.13). Ведь пакеты всегда отличаются друг от друга и к тому же сдвинуты друг относительно друга во времени. Именно по выходу уровня постоянной составляющей за установленные пределы и определяет каждый сетевой адаптер наличие коллизии в сети.
Определение факта коллизии в шине при использовании манчестерского кода
Рис. 4.13. Определение факта коллизии в шине при использовании манчестерского кода
Задача обнаружения коллизии существенно упрощается, если используется не истинная шина, а равноценная ей пассивная звезда (рис. 4.14).
Обнаружение коллизии в сети пассивная звезда
Рис. 4.14. Обнаружение коллизии в сети пассивная звезда
При этом каждый абонент соединяется с центральным концентратором, как правило, двумя кабелями, каждый из которых передает информацию в своем направлении. Во время передачи своего пакета абоненту достаточно всего лишь контролировать, не приходит ли ему в данный момент по встречному кабелю (приемному) другой пакет. Если встречный пакет приходит, то детектируется коллизия. Точно так же обнаруживает коллизии и концентратор.
Управление обменом в сети с топологией кольцо
Кольцевая топология имеет свои особенности при выборе метода управления обменом. В этом случае важно то, что любой пакет, посланный по кольцу, последовательно пройдя всех абонентов, через некоторое время возвратится в ту же точку, к тому же абоненту, который его передавал (так как топология замкнутая). Здесь нет одновременного распространения сигнала в две стороны, как в топологии шина. Как уже отмечалось, сети с топологией кольцо бывают однонаправленными и двунаправленными. Наиболее распространены однонаправленные.
В сети с топологией кольцо можно использовать различные централизованные методы управления (как в звезде), а также методы случайного доступа (как в шине), но чаще выбирают все-таки специфические методы управления, в наибольшей степени соответствующие особенностям кольца.
Самые популярные методы управления в кольцевых сетях маркерные (эстафетные), те, которые используют маркер (эстафету) – небольшой управляющий пакет специального вида. Именно эстафетная передача маркера по кольцу позволяет передавать право на захват сети от одного абонента к другому. Маркерные методы относятся к децентрализованным и детерминированным методам управления обменом в сети. В них нет явно выраженного центра, но существует четкая система приоритетов, и потому не бывает конфликтов.
Работа маркерного метода управления в сети с топологией кольцо представлена на рис. 4.15.
Рис. 4.15. Маркерный метод управления обменом (СМ—свободный маркер, ЗМ— занятый маркер, МП— занятый маркер с подтверждением, ПД—пакет данных)
По кольцу непрерывно ходит специальный управляющий пакет минимальной длины, маркер, предоставляющий абонентам право передавать свой пакет. Алгоритм действий абонентов:
1. Абонент 1, желающий передать свой пакет, должен дождаться прихода к нему свободного маркера. Затем он присоединяет к маркеру свой пакет, помечает маркер как занятый и отправляет эту посылку следующему по кольцу абоненту.
2. Все остальные абоненты (2, 3, 4), получив маркер с присоединенным пакетом, проверяют, им ли адресован пакет. Если пакет адресован не им, то они передают полученную посылку (маркер + пакет) дальше по кольцу.
3. Если какой-то абонент (в данном случае это абонент 2) распознает пакет как адресованный ему, то он его принимает, устанавливает в маркере бит подтверждения приема и передает посылку (маркер + пакет) дальше по кольцу.
4. Передававший абонент 1 получает свою посылку, прошедшую по всему кольцу, обратно, помечает маркер как свободный, удаляет из сети свой пакет и посылает свободный маркер дальше по кольцу. Абонент, желающий передавать, ждет этого маркера, и все повторяется снова.
Приоритет при данном методе управления получается географический, то есть право передачи после освобождения сети переходит к следующему по направлению кольца абоненту от последнего передававшего абонента. Но эта система приоритетов работает только при большой интенсивности обмена. При малой интенсивности обмена все абоненты равноправны, и время доступа к сети каждого из них определяется только положением маркера в момент возникновения заявки на передачу.
В чем-то рассматриваемый метод похож на метод опроса (централизованный), хотя явно выделенного центра здесь не существует. Однако некий центр обычно все-таки присутствует. Один из абонентов (или специальное устройство) должен следить, чтобы маркер не потерялся в процессе прохождения по кольцу (например, из-за действия помех или сбоя в работе какого-то абонента, а также из-за подключения и отключения абонентов). В противном случае механизм доступа работать не будет. Следовательно, надежность управления в данном случае снижается (выход центра из строя приводит к полной дезорганизации обмена). Существуют специальные средства для повышения надежности и восстановления центра контроля маркера.
Основное преимущество маркерного метода перед CSMA/CD состоит в гарантированной величине времени доступа. Его максимальная величина, как и при централизованном методе, составит (N-1)• tпк, где N – полное число абонентов в сети, tпк – время прохождения пакета по кольцу. Вообще, маркерный метод управления обменом при большой интенсивности обмена в сети (загруженность более 30—40%) гораздо эффективнее случайных методов. Он позволяет сети работать с большей нагрузкой, которая теоретически может даже приближаться к 100%.
Метод маркерного доступа используется не только в кольце (например, в сети IBM Token Ring или FDDI), но и в шине (в частности, сеть Arcnet-BUS), а также в пассивной звезде (к примеру, сеть Arcnet-STAR). В этих случаях реализуется не физическое, а логическое кольцо, то есть все абоненты последовательно передают друг другу маркер, и эта цепочка передачи маркеров замкнута в кольцо (рис. 4.16). При этом совмещаются достоинства физической топологии шина и маркерного метода управления.
Применение маркерного метода управления в шине
Рис. 4.16. Применение маркерного метода управления в шине
Событие - это какое-либо действие, осуществляемое пользователем либо браузером. Например, когда мы щелкаем (кликаем) на ссылке - осуществляется событие, его перехватывает специальный обработчик и перенаправляет нас на нужную страницу; при наведении курсора (указателя мыши) на ссылку в строке состояния (обычно находится в нижней части окна браузера) отображается адрес, так как обработчик "наведения курсора на объект (в данном случае на ссылку)" помещает туда этот адрес и так далее...
а). onmouseout и onmouseover
Для начала наведем курсор на кнопку "Сброс" или "Отправить" и обратим внимание на строку состояния. Вы должны увидеть там надпись с объяснением значения кнопки. Теперь отведите курсор и строка состояния очистится.
Содержимое строки состояния хранится в переменной window.status. Переменная это некоторый объект (можно представить себе ящик), значение которого (содержимое которого) можно изменять. Изменение значения осуществляется операцией присваивания (=), а выглядит она следующим образом:
имя_переменной = "значение"; (какие использовать кавычки: одинарные или двойные значения не имеет)
Поэтому для того, чтобы изменить надпись в строке состояния, нам нужно присвоить переменной window.status нужное нам значение (подсказку к кнопке), а когда курсор будет убран - присвоить пустую строку("").
Вся задача сводится к тому, чтобы определить когда пользователь наводит курсор на кнопку, а когда убирает его. Для этого нужно "сказать" обработчикам этих событий выполнить нужное нам действие. Обработчик события "наведение курсора" - onmouseover, а "отведение курсора" - onmouseout.
Очень многие тэги имеют атрибуты, начинающиеся с on (onclick, onmouseout, onfocus и т. д.). Значение этих атрибутов и есть, задача которую необходимо выполнить соответствующему обработчику. То есть для обработчика onmouseout есть атрибут onmouseout, для onmouseover - onmouseover. И в итоге мы получаем следующее определение кнопок:
Как Вы видите, атрибут onmouseover имеет в качестве значения JavaScript-код: window.status='Щелкните для отправки данных', как только курсор достигает кнопки, обработчик события mouseover - onmouseover, смотрит, что хранится в атрибуте onmouseover и выполняет необходимое действие(присвоение значения переменной window.status). Аналогично действует и обработчик события onmouseout: как только курсор уводиться от кнопки (то есть выполняется событие mouseout), то обработчик события - onmouseout выполняет код, содержащийся в атрибуте onmouseout.
То же самое и со второй кнопкой.
б). <a href="Java Scriptfunction()">Function</a>
Теперь щелкните на ссылке и откроется окошко с подсказкой. Но заметьте, что окно небольших размеров и у него нет панели инструментов - такого силами html не сделаешь! В данном примере мы имеем окно размером 300x200, без панелей инструментов, содержащее документ help.html.
Для того чтобы создать такое окошко существует следующий JavaScript-код:
где:
1. helpWindow - это имя переменной (как window.status, только в данном случае имя выбирается произвольно). Эта переменная нужна для последующей работы с окном (например, закрыть его нестандартным способом - с помощью JavaScript-сценария).
- Зачем? Не проще ли указывать просто имя открывающейся страницы, например help.html?
- А если у нас две копии одной и той же страницы? Или две страницы с одинаковым именем(например, в разных папках)? Вот для того, чтобы не перепутать страницы и свободно работать именно с тем окном с которым предполагаешь и сделанно, так чтобы "окно" присваивалось переменной, так как имя переменной можно выбрать любое.
2. window.open(что-то) - это функция. Функции выполняют определенную задачу, в данном случае window.open() открывает новое окно.
3. help.html - это страница, которую нужно открыть.
4. "" - В кавычках должно быть имя окна, но оно нам не пригодится, поэтому там нулевая строка. В следующих кавычках указываются "параметры открываемого окна": оно не должно содержать панели инструментов (toolbar=0) и должно быть шириной 300 пикселей, а высотой - 200 (width=300,height=200, соответственно).
Теперь все, что нужно это по событию "щелчка" выполнить этот код, однако есть два "но". Во-первых строка очень длинная, чтобы присвоить ее какому-либо атрибуту - будет некрасиво смотреться, да и вызывать неудобства при чтении кода страницы. Во-вторых, первоначальное предназначение ссылки - это переход на другую страницу, но нам переходить никуда не нужно, нам нужно выполнить вместо этого JavaScript-код.
Первое решается написанием функции. Как я уже говорил функция выполняет некоторую задача, причем для использования функции достаточно указать ее имя. Можно не только использовать предопределенные(функции, которые имеется в языке и без нас), но и писать их самому. Обычно функции определяются(пишутся) в разделе HEAD документа, в котором используются:
"function" значит, что дальше будет написана наша функция; help() - это имя функции (оно будет указываться вместо тела функции (между { и })).
Вторая проблема решается тоже довольно просто. Адрес страницы указывается в атрибуте href, а нам надо выполнить JavaScript код вместо перехода по ссылке:
"Java Script" означает, что дальше должен идти JavaScript-код, и что он должен выполняться вместо стандартного перехода по ссылке. В данном случае наш JavaScript-код - это созданная нами функция help().
в). onclick
Нам не остается ничего более, как закрыть окно со справкой. Для этого воспользуемся кнопкой "Закрыть". Но нас интересует то, как работает эта кнопка, а имеет она следующий вид:
Дабы закрыть окно мы сделали щелчок(Click) на кнопке "Закрыть", а щелчок это нажатие и отпускание кнопки мыши, причем и то и другое должно быть произведено на одном и том же элементе (например, на кнопке). Кликая, на кнопке мы активируем обработчик события onClick, который выполняет для нас JavaScript-код, прописанный в атрибуте onclick нашей кнопки. Помните мы открывали окно? Мы писали window.open(), а здесь тоже самое только window.close(). window - это текущее окно, а close() - закрыть.
Это одно из наиболее частоупотребляемых событий.
г). onfocus и onblur
Ну что ж будем ближе подбираться к вводу требуемой от нас информации.
Как я уже говорил: элемент получает фокус когда на нем происходит нажатие кнопки мыши, или на него осуществляется переход посредством клавиши табуляции (Tab), а теряет, когда фокус получает другой элемент. Наше поле для ввода получит фокус тогда, когда пользователь решиться ввести информацию. При этом было бы удобно, чтобы текст с подсказкой ("Введите Ваше имя") автоматически выделялся и посетитель мог его удалить одним нажатием на del, а не удалять по одному символу, или выделять текст вручную. Удобство пользователя свято. Итак, для этого мы воспользуемся событием focus. Для выделения текста используется метод select(). То есть атрибутом к полю надо прописать: onfocus="this.select();", this обозначает, что выделение должно происходить именно в этом текстовом поле (а можно прописать путь и к другому, но это не целесообразно).
А теперь попробуйте ничего не изменяя (или все удалив) убрать фокус (например, щелкнув в любом месте окна, или нажав Tab). Это событие blur, я прописал в нем выполнение функции: onblur="check();". Сама же функция имеет следующий вид (в разделе head страницы с формой между <script> и </script>):
document.forms[0].name.value - это то, что введено в текстовое поле. document - это текущий документ, forms[0] - первая форма на нашей страницы (отсчет с нуля), name = имя поля (задается атрибутом name (<input name="name">)), а value это и есть нужное нам значение (то, что введенно в текстовое поле, к которому м ы и написали путь). Введенное в поле мы присваиваем переменной val (var значит, что дальше идет имя переменной), чтобы в дальнейшем каждый раз не писать весь путь целиком.
Следующее это оператор if(если). Он выглядит следующим образом:
Мы сравниваем содержание переменной val с пустой строкой ('') и с начальной строкой ('Введите Ваше имя'). Обратите внимание, что сравнение не как в математике(с одним =), а сравниваются двума ==. || - или. Функция alert выводит окно с ошибкой (то, что в скобках - это текст ошибки). То есть:
И на всякий случай приведу целиком строку с кодом поля input:
д). onreset и onsubmit
Допустим, что пользователь заполнил форму неправильно, и он хочет очистить все поля формы одновременно: для этого он воспользуется стандартной кнопкой reset. Но что если пользователь щелкнет на ней по случайности (рука дрогнет, или в суете спутает с кнопкой submit), а форма была огромная, и он долго мучился ее заполнять..., ему будет грустно, и еще он будет долго материться. Поэтому хорошо бы у него дополнительно спросить: действительно ли он хочет очистить форму.
Вообще событие reset обрабатывается до очистки формы. А чтобы отменить очистку вообще, нам просто напросто надо вернуть обработчику события значение false, то есть прописать в соответствующем атрибуте: "return false;", а чтобы продолжить очистку: "return true;". А теперь вспомним функцию, которая выдает вопрос пользователю на подтверждение чего-либо, эта функция: "confirm('Вопрос?');". При нажатии "Ok", эта функция заменяется на true, а при нажатии "Cancel" на false. То есть все что от нас требуется, это прописать в теге <form> атрибут: onreset="return confirm('Вы действительно хотите сбросить форму?');". Тогда при нажатии "Ok" там на самом деле будет "return true;", и форма будет очищена, а если "Cancel", то "return false;" и очистка формы будет отменена.
Подобным образом действует событие submit, которое возникает при попытке отправить форму. Поскольку в нашем случае форму отправлять никуда не надо, то у меня просто написано: onsubmit="return false;". И сколько бы Вы не щелкали ничего не изменится (разве что Вы JavaScript отключите).
Обычно же обработчик onsubmit используется для верификации формы (то есть проверки на заполнение всех необходимых полей, правильность их заполнения, скажем, проверка по определенному шаблону и т. п.), для этого создается функция, которая выполняет все действия. Функция должна содержать операторы "return true" и "return false", которые позволяют, заменить функцию на true или false, соответственно, в зависимости от результатов проверки (если успешно, то true, если нет false). Но верификация данных это обширная тема, которая не может быть рассмотрена здесь. Один из примеров базовой верификации я привел, когда объяснял событие blur - подобную функцию можно использовать и здесь. Тогда <form> будет содержать атрибут: onsubmit="return function();".
Но не забывайте, что нельзя ограничиваться одной лишь проверкой языком JavaScript, ибо его поддержка может быть отключена у посетителя, и тогда все Ваши труды по защите...
е). onmousedown и onmouseup
Еще одна пара событий не нашла достойного места на странице, но я ее реализовал в виде кнопки "Button". Причем это не обычная html-кнопка, она реализована в виде двух картинок. Исходная кнопка хранится в файле с именем npressed.jpg, а нажатая - pressed.jpg. Чтобы достичь эффекта нажатия кнопки нам необходимо, чтобы при при щелчке на ней(this) значение атрибута src (путь к картинке) тега <img> менялось на pressed.jpg, а при отпускании обратно на npressed.jpg. Нажатие кнопки обрабатывает onmousedown, а отпускание - onmouseup, то есть здесь все просто:
ж). onload, onunload и onabort
Обработчик события onload активируется, когда начинает загружаться графическая часть страницы (все тексты, графика и т.п.). onload является атрибутом тега <body>. Если честно я не вижу сколько бы реального применения этому событию, зато я нашел, что можно сделать с onunload. onunload это тоже атрибут тега <body>. Событие unload происходит когда мы пытаемся покинуть данную страницу (переходим по ссылке на другую, закрываем окно браузера, обновляем страницу и т. д.). Откройте еще раз окошко справки. Допустим, что пользователь прочитал справку, и хочет отправить форму, или уйдет с нашего сайта, но при этом он забыл закрыть это маленькое окошко с подсказкой, мы на выходе закроем его сами. А для этого тег <body> (у начального документа) у нас будет выглядеть следующим образом:
Вы должны бы помнить, что helpWindow это имя нашего окна (ведь именно этой переменной мы присваивали его открытие: helpWindow = window.open("help.html", "", "toolbar=0,width=300,height=200")), а метод close() закрывает это окно. Некоторые нехорошие люди используют это событие, чтобы когда посетители уходили с его страницы, появлялись какие-либо окна, так называемые pop-up.
onabort - атрибут тега <img>. Когда пользователь отменяет загрузку изображения происходит событие abort. Но отмена загрузки изображения может не входить в наши плане. И в качестве предупреждения у нас может быть написано нечто похожее на
ЗАКЛЮЧЕНИЕ
Есть некоторые события о которых я здесь нарочно не упомянул, потому что не нашел им достойного применения, но Вам они возможно пригодятся, поэтому я уделю им немного внимания.
onchange - обработчик события, который активируется, когда Вы изменяете содержимое текстового элемента или текстовой области (<TEXTAREA>) (например, когда Вы вводите или удаляете очередную букву какого-либо текстового поля).
onselect - обработчик события выбора текста. То есть это событие происходит, когда пользователь пытается выделить текст в текстовом элементе или текстовой области.
onerror - обработчик события error, которое возникает при ошибке загрузки документа или изображения (то есть onerror это атрибут тегов <body> и <img>). Оно возникает при синтаксической ошибке JavaScript-кода (но Вы ведь не будете специально делать в нем ошибки), либо ошибкой времени выполнения (например, если Ваш скрипт выполняет какие-либо вычисления и у Вас по ошибке получится так, что некое число будет делиться на ноль, а это недопустимо - это и есть одна из ошибок времени выполнения).
Так же не забывайте, что я привел лишь по одному примеру из десятков возможных на каждое событие. Здесь главное Ваша фантазия и навыки. Например, события mouseout, mouseover, mouseup, mousedown часто используются для создания выпадающих меню и других визуальных эффектов, но это весьма трудный материал, который требует более глубоких знаний, причем не одного JavaScript.
В этой статье описываются полезные функции и процедуры, помогающие эффективно работать с различными типами данных в системе "1С:Предприятие 7.7".
Форматирование данных в 1С
Список значений в 1С
Таблица значений в 1С
Таблица или печатная форма в 1С
Периоды и даты в 1С
Календари и праздники в 1С
[pagebreak]
Справочники в 1С
Документы в 1С
Предопределённые функции и процедуры в 1С
Налоговый учёт и первое событие в 1С
Резюме
В статье описаны функции и процедуры, используемые в программе "1С:Предприятие 7.7" для работы со справочниками, документами, списками значений, таблицами значений и с прочими агрегатными типами данных. Образцы практического применения описанных средств Вы сможете найти в статьях "Отчёты для 1С" и "Обработки для 1С".
На сегодняшний день музыкальные магазины online, наподобие Musikload[1], становятся все более распространенными и пользуются бешенной популярностью. В этой статье мы расскажем как можно читать мета-информацию mp3-файла средствами PHP, что поможет вам в создании каталога музыки. Это очень просто, поддержка базы данных не нужна.
Откуда знает MP3-Player, например Winamp информацию об исполнителе или названии композиции, которую он проигрывает? Может быть, он сам каким-то чудным образом узнает название песни и альбома? Нет, здесь нет никакого волшебства! Подобная информация содержится в самих файлах. Музыкальные файлы других форматов таких как WMA или Ogg Vorbis также содержат подобную информацию, но здесь речь пойдет о файлах в формате mp3.
Спецификация mp3 определяет способ хранения музыкальных данных, однако не предусматривает никакой возможности для сохранения метаданных композиции, таких как название и исполнитель. Чтобы обойти это ограничение был разработан стандарт ID3. Согласно этой спецификации, метаданные должны быть помещены в так называемые ID3-теги, которые независимо от используемого стандарта ID3, помещаются в конец или начало файла. ID3-теги версии 1 (ID3v1-Tags) представляют собой простейшую конструкцию, которая дописывается в конец файла. Ее объем не должен превышать 128 байт. Структура тега такова: после строкового значения “TAG» следует информация о названии (30 символов), исполнителе (30 символов), альбоме (30 символов), годе записи (четырехзначное число), комментарий (30 символов), жанр (1 байт). Тег с подобной структурой обозначается как ID3v1.0-Tag. В дополнение к этому существует еще стандарт ID3v1.1-Tag, который встречается значительно чаще, поскольку позволяет сохранять информацию о порядковом номере композиции в альбоме. Вследствие этого был урезан до 28 символов размер комментария. Сразу после комментария следует нуль-байт, а последующий байт содержит информации о номере трэка. На иллюстрации один и два видна структура обоих стандартов.
PEAR придет на помощь!
Для считывания информации из ID3v1 тегов, в библиотеку PEAR уже был включен пакет MP3_Id[3], который поможет Вам без проблем извлекать информацию из тега, или наоборот записывать. Если в файл отсутствует ID3-тег, вы можете его создать. Листинг 1 показывает как можно считывать информацию из тегов. Создается объект класса MP3_ID, считывается файл, а затем метод getTag() извлекает данные, которые помещаются для дальнейшей обработки в отдельные поля объект. Листинг 2 показывает результат действия программы листинга 1. Общий обзор доступных полей вы найдете в документации по пакету на домашней странице PEAR.
Листинг 1:
Листинг 2:
Листинг 3 показывает как просто можно изменять содержимое ID3-тегов и создавать их. Сначала, как это было показано в Листинге 1, создаем объект класса MP3_ID, считываем файл, а с помощью метода setTag($fieldname, $value) помещаем в тег нужную информацию. Хотите удалить все теги? Тогда посмотрите на листинг 4, где показано как можно сделать это. Для удаления тегов используется метод remove(), а остальное вы уже знаете. Необходимо дополнить, что MP3_Id обладает другими полезными функциями, которые вам позволят перенести содержимое тега из одного файла в другой или сформировать массив, содержащий все музыкальные направления. Для получения дополнительной информации смотрите документацию.
Listing 3:
Listing 4:
Используем PECL
В конце лета 2004 года появилось расширение PHP ext/id3[7]. Разрабатывается в рамках PECL[6]. В отличие от MP3_ID эта библиотека написана не на PHP, а на C, поэтому она должно работать несколько быстрее. Однако библиотека не входит в стандартный комплект PHP-исходников, к тому же на сегодняшний день отсутствует стабильная версия, хотя функции отвечающие за чтение и запись ID3-тегов считаются стабильными.
Если вы хотите использовать именно это расширение, для установки необходимо воспользоваться либо PEAR-installer, либо откомпилировать php, включив поддержку данного расширения. Если вы используете WINDOWS, существует возможность скачать уже откомпилированную DLL для версии php 5.0 или 5.01 с сайта PHP-Snapshot[9], поместить ее в каталог с расширениями php (например c:phpext), подключить через php.ini. Чтобы воспользоваться расширением, вы должны иметь PHP 4.3 или более позднюю версию, поскольку библиотека использует Streams-API.
Само собой разумеется, библиотека позволяет изменять содержимое ID3-тегов. Для этого вам не нужно ничего, кроме массива, представленного в листинге 6, и функции id3_set_tag(). В качестве первого параметра функция принимает имя изменяемого mp-3 файла, а в качестве второго - массив с необходимыми данными. Третий параметр необязателен и представляет собой константу, указывающую версию ID3-тега. В существующей версии библиотеки функция id3_set_tag() может работать только с тегами версии 1.0 или 1.1. Листинг 7 содержит необходимый php-код. В дополнение к этому, листинг 8 показывает как с помощью функции id3_remove_tag можно удалить существующий ID3-тег.
Ext/id3 содержит еще несколько полезных функций, которые позволяют определить версию ID3-тега (id3_get_version) или манипулируют со списком музыкальных направлений и их id, представленных в виде целого числа типа integer. Надо сказать, что данное число мало подходит для указания музыкального направления.
Listing 5:
Listing 6:
Listing 7:
Следующее поколение
Несмотря на то, что с помощь ID3v1-тегов уже можно сохранять важнейшую информацию о содержимом mp3-файла, уже проявляются ограничения версий 1.0 и 1.1:
из-за фиксированного размера тега ограничен объем сохраняемой информации
ограничено количество сохраняемых атрибутов
Как мы видим, расширить объем пространства, отведенный под ID3v1 теги нельзя, Существую трудности с сохранением информации о названии композиции, исполнителе, альбоме, комментарии, если размер данных превышает 30 символов. Допустим, вам нужно указать название The Hitchhiker's Guide to the Galaxy, используя стандарт ID3v1, вы можете сохранить лишь The Hitchhiker's Guide to. Та же ситуации наблюдается с указанием музыкального направления. Для этого выделяется только один байт, вследствие этого количество музыкальных направлений не может превышать 256. Наверное, сегодня этого достаточно, но кто знает, сколько в будущем появится еще музыкальных направлений.
Чтобы преодолеть указанные ограничения был введены ID3-теги версии 2[2], или короче ID3v2. ID3v2-теги записываются в начало файла, собственно перед самими аудио данными. Информация организована в отдельные единицы, которые обозначаются как фреймы. ID3v2 - это формат-контейнер, то есть, существует возможность при изменении тега вводить новые фреймы. Из этого следует, что ID3v2 может содержать значительно больше информации, чем ID3v1. Это может быть информация об авторских правах, битрейте, (BMP) или, наконец, полный текст песни или изображения. В дополнение к этому можно по желанию добавлять новые фреймы. Вот важнейшие достоинства данного формата:
Никаких ограничений на объем сохраняемой информации
Гибкость и расширяемость
Возможность сжатия содержимого тегов
Поддержка Unicode
Возможность хранить бинарные данные, например изображения и файлы.
Из-за расширенных возможностей ID3v2-теги, несколько труднее поддаются считыванию, чем ID3v1-теги. Хорошая новость состоит в том, что ext/id3 уже позволяет извлекать важнейшую информацию. Если вы исполните код, помещенный в листинг 9, вы получите тот же результат, что и в листинге 10. Проделав это, вы сможете убедиться, что объем выводимых данных значительно шире, чем тот, что показан в листингах 5 и 6.
Каждый фрейм ID3v2-тега обладает уникальным ID. Ext/id3 содержит две функции, которые позволяют узнать содержимое фрейма. Это id3_get_frame_short() и id3_get_frame_long_name(). В качестве параметра они принимают id фрейма и возвращают его описание.
В будущих версиях ext/id3 будет содержать другие полезные функции, которые позволят считывать или записывать фреймы, соответствующие спецификации ID3.
Листинг 8:
Listing 9:
Дополнительная информация
Прежде чем вы организуете бизнес, связанный с продажей музыкальных композиций online, мы вам расскажем еще о нескольких полезных возможностях библиотеки MP3_Id. С помощью нее можно не только считывать информацию ID3- тегов, она позволяет получить некоторую интересную информацию о самом mp3-файле. Речь идет о битрейте, длительности звучания и других полезных свойствах. Подобные сведения можно получить при помощи метода study(), а дальше посредством метода getTag(), можно выбирать необходимые данные. Листинг 12 показывает как это работает. Результат работы программы показан в листинге 13. К сожалению, эти возможности недостаточно документированы, т.е. трудно разобраться какой атрибут можно считать при помощи getTag() или изменить посредство setTag(). В этом случае необходимо изучить код модуля MP3/Id.php.
Listing 10:
Listing 11:
Listing 12:
Listing 13:
Выводы
В этой статье мы рассмотрели существующие возможности извлечения информации из mp-3 файлов средствами PHP. Обе библиотеки (MP3_Id и id3) легки в использовании и содержать необходимые функции. Одна библиотека написана на PHP, другая на C. Выбор того или иного варианта определяется вашими предпочтениями и возможностями хостинга.
Авторы
Карстен Луке изучает информатику в высшей школе Бранденбурга. Совместно со Стефаном Шмидтом разработывает расширение id3. Вы можете связаться с ним по e-mail ( luckec@php.net ) или посетить его сайт ( www.tool-gerade.de ) Стефан Шмидт - разработчик веб-приложений фирмы 1&1 Internet AG, активно учавствует в развити PEAR и PECL. Вы можете связаться с ним по e-mail ( schst@php.net )
В состав библиотеки MFC входит ряд классов, представляющих стандартные диалоговые панели. Эти классы позволяют легко реализовать такие часто используемые операции, как открытие и сохранение файла, выбор цвета, выбор шрифта и т.д. Все эти классы наследуются от CCommonDialog, который в свою очередь является производным по отношению к базовому классу CDialog.
Приведем классы стандартных диалоговых панелей и их назначение:
CColorDialog - Панель для выбора цвета
CFileDialog - Панель выбора файлов для открытия и сохранения на диске
CFindReplaceDialog - Панель для выполнения операции поиска и замены
CFontDialog - Панель для выбора шрифта
CPrintDialog - Панель для вывода документа на печать
CPageSetupDialog - Панель выбора формата документа
COleDialog - Панель для управления технологией OLE
Классы, управляющие стандартными диалоговыми панелями, определены в файле afxdlgs.h. Поэтому при использовании этих классов в приложении необходимо включить этот файл в исходный текст при помощи директивы #include.
Панель выбора цвета (класс CColorDialog)
Чтобы отобразить на экране стандартную диалоговую панель выбора цвета, надо создать объект класса CColorDialog, а затем вызвать метод DoModal. При создании объекта класса СColorDialog используется следующий конструктор:
Все параметры конструктора необязательны, однако в некоторых случаях использование этих параметров может помочь.
Первый параметр clrInit позволяет указать цвет, выбранный по умолчанию сразу после открытия диалоговой панели. Если параметр не будет указан, в качестве цвета, выбранного по умолчанию, будет использоваться черный цвет.
Параметр dwFlags содержит набор флагов, управляющих диалоговой панелью выбора цвета. При помощи него блокировать или разрешать работу некоторых элементов управления диалоговой панели выбора цвета. Если при создании объекта класса CColorDialog не указать параметр dwFlags, тем не менее можно выполнить настройку диалоговой панели, обратившись непосредственно к элементу m_cc данного класса. Параметр dwFlags, указанный в конструкторе, используется для инициализации m_cc. Изменения в элемент m_cc должны быть внесены до того, как панель будет отображаться на экране.
Последний параметр pParentWnd можно использовать, чтобы указать родительское окно диалоговой панели.
Методы класса CСolorDialog
Чтобы вывести диалоговую панель выбора цвета на экран, необходимо использовать метод DoModal. После отображения панели на экране пользователь может выбрать из нее цвет и нажать кнопки OK или Cancel для подтверждения выбора цвета или отказа от него. Когда диалоговая панель закрывается, метод DoModal возвращается значения IDOK и IDCANCEL, в зависимости от того, какую кнопку нажал пользователь:
На экране появится стандартная диалоговая панель выбора цвета Color. В верхней половине диалоговой панели расположены 48 прямоугольников, имеющих различные цвета. Они представляют так называемые основные цвета (Basic colors). Можно выбрать один из этих цветов и нажать кнопку OK. После того, как диалоговая панель закрыта (метод DoModal завершил свою работу), можно воспользоваться методами класса CColorDialog, чтобы узнать цвета, выбранные пользователем.
Для определения цвета, выбранного пользователем, можно обратиться к методу GetColor класса CColorDialog. Данный метод возвращает значение COLORREF, соответствующее выбранному цвету.
Если пользователю недостаточно основных цветов, представленных в диалоговой панели Color, он может выбрать до 16 дополнительных цветов. Для этого он должен нажать кнопку DefineCustom Colors. Диалоговая панель изменит свой внешний вид - появятся дополнительные органы управления, позволяющие выбрать любой из 16 777 216 цветов. Когда цвет выбран, нужно нажать кнопку Add Custom Colors. Выбранный цвет будет добавлен к дополнительным цветам (Custom colors) - один из свободных прямоугольников окрасится соответствующим цветом.
При помощи метода GetSavedCustomColors класса CColorDialog можно определить дополнительные цвета, выбранные пользователем в диалоговой панели Color. Этот метод возвращает указатель на массив из 16 элементов типа COLORREF. Каждый элемент массива описывает один дополнительный цвет.
Когда диалоговая панель Color отображается приложением первый раз, все прямоугольники, отображающие дополнительные цвета, имеют белый цвет. Дополнительные цвета, выбранные пользователем, сохраняются во время работы приложения. После перезапуска приложения дополнительные цвета сбрасываются.
Панель выбора файлов (класс CFileDialog)
Среди стандартных диалоговых панелей, для которых в библиотеке MFC создан специальный класс, есть панели для работы с файловой системой - Open и Save As. Диалоговая панель Open позволяет выбрать один или несколько файлов и открыть их для дальнейшего использования. Диалоговая панель Save As позволяет выбрать имя файла для записи в него документа.
Для управления диалоговыми панелями Open и Save As предназначен один класс CFileDialog. Рассмотрим конструктор класса CFileDialog более подробно:
Объекты класса CFileDialog представляют диалоговые панели Open или Save As в зависимости от параметра bOpenFileDialog. Если параметр bOpenFileDialog содержит значение TRUE, то создается объект, управляющий диалоговой панелью Open, а если FALSE - диалоговой панелью Save As.
Параметр bOpenFileDialog является единственным обязательным параметром, который необходимо указать. Остальные параметры конструктора класса CFileDialog задают различные режимы работы панели и могут не указываться.
Чтобы создать объект класса CFileDialog , представляющий диалоговую панель для открытия файлов (mFileOpen), и объект, представляющий диалоговую панель для сохранения файлов (mFileSaveAs), можно воспользоваться следующими вызовами конструктора класса:
Во многих случаях имена файлов, которые нужно открыть или закрыть, имеют определенное расширение. Параметр lpszDefExt позволяет задать расширение файлов, используемое по умолчанию. То есть, если пользователь при определении имени файла не укажет расширение, имени файла автоматически присваивается расширение, принятое по умолчанию. Если при определении свойств диалоговой панели программист присвоит параметру lpszDefExt значение NULL, то расширение файлов должно задаваться пользователем явно.
В некоторых случаях требуется, чтобы диалоговые панели отображались с уже выбранным именем файла. Чтобы указать имя файла, используемое по умолчанию, применяется параметр lpszFileName. Если параметр lpszFileName имеет значение NULL, данная возможность не реализуется.
С помощью флага dwFlags можно изменить внешний вид и некоторые другие характеристики стандартных диалоговых панелей класса CFileDialog. В него можно записать комбинацию флагов, управляющих различными характеристиками этих панелей. Например, флаг OFN_HIDEREADONLY означает, что из диалоговой панели удаляется переключатель "Read Only", а флаг OFN_OVERWRITEPROMPT (используемый для панели Save As) - что необходимо выводить диалоговую панель с предупреждением, если пользователь выбирает для сохранения имя уже существующего файла.
Диалоговые панели выбора файлов обычно имеют список так называемых фильтров, включающих названия типов файлов и расширения имен файлов данного типа. Выбрав фильтр, пользователь указывает, что он желает работать только с файлами определенного типа, имеющими соответствующее расширение. Файлы с другими расширениями в диалоговых панелях не отображаются.
Список фильтров можно указать через параметр lpszFilter. Одновременно можно указать несколько фильтров. Каждый фильтр задается двумя строками - строкой, содержащей имя фильтра, и строкой, в которой перечислены соответствующие ему расширения имен файлов. Если одному типу соответствует несколько расширений, они разделяются символом ;. Строка, содержащая имя фильтра, отделяется от строки с расширениями файлов символом |. Если используется несколько фильтров, то они также отделяются друг от друга символом |. Например, в качестве строки, задающей фильтры, можно использовать строку вида:
Диалоговые панели, представленные объектами класса CFileDialog, могут иметь или не иметь родительского окна. Чтобы указать родительское окно, нужно передать конструктору CFileDialog указатель на него через параметр pParentWnd.
Методы класса CFileDialog
Создание объекта класса CFileDialog еще не вызывает отображения соответствующей диалоговой панели. Для этого необходимо воспользоваться методом DoModal класса CFileDialog.При вызове метода DoModal для ранее созданного объекта класса CFileDialog на экране открывается соответствующая диалоговая панель. После того, как пользователь завершает работу с диалоговой панелью, метод DoModal вернет значение IDOK или IDCANCEL в случае успешного завершения и нуль - в случае возникновения ошибок:
После того, как пользователь закроет диалоговую панель и метод DoModal вернет управление, можно воспользоваться другими методами класса CFileDialog , чтобы определить имена выбранных файлов:
GetPathName - Определяет полный путь файла
GetFileName - Определяет имя выбранного файла
GetFileExt - Определяет расширение имени выбранного файла
GetFileTitle - Позволяет определить заголовок выбранного файла
GetNextPathName - Если диалоговая панель позволяет выбрать сразу несколько файлов, то этот метод можно использовать для определения полного пути следующего из выбранных файлов
GetReadOnlyPref - Позволяет узнать состояние атрибута "только для чтения" (read-only) выбранного файла
GetStartPosition - Возвращает положение первого элемента из списка имен файлов
Наиболее важный метод - GetPathName. Он получает полный путь файла, выбранного из диалоговых панелей Open или Save As. Если диалоговая панель позволяет выбрать сразу несколько файлов, тогда метод GetPathName возвращает массив строк, состоящий из нескольких строк, заканчивающихся двоичным нулем. Первая из данных строк содержит путь к каталогу, в котором расположены выбранные файлы, остальные строки содержат имена выбранных файлов. Выделение строки, содержащей путь к каталогу, проблем не вызывает, а чтобы получить имена выбранных файлов, необходимо воспользоваться методами GetStartPosition и GetNextPathName.
[pagebreak]
Метод GetStartPosition возвращает значение типа POSITION. Оно предназначено для передачи методу GetNextPathName и получения очередного имени выбранного файла. Если пользователь не выбрал ни одного файла, метод GetStartPosition возвращает значение NULL. Значение, полученное этим методом, следует записать во временную переменную типа POSITION и передать ссылку на нее методу GetNextPathName. Метод GetNextPathName вернет полный путь первого из выбранных в диалоговой панели файлов и изменит значение переменной pos, переданной методу по ссылке. Новое значение pos можно использовать для последующих вызовов метода GetNextPathName и получения путей всех остальных выбранных файлов. Когда метод GetNextPathName вернет имена всех выбранных файлов, в переменную pos записывается значение NULL.
В панелях Open и Save As имеется переключатель "ReadOnly". По умолчанию этот преключатель не отображается. Если есть необходимость воспользоваться этим переключателем, то нужно отказаться от использования флага OFN_HIDEREADONLY.
Метод GetReadOnlyPref позволяет определить положение переключателя "ReadOnly". Если переключатель включен, то метод GetReadOnlyPref возвращает ненулевое значение. В противном случае GetReadOnlyPref возвращает нуль.
Панель выбора шрифта (класс CFontDialog)
Стандартная диалоговая панель Font предназначена для выбора шрифта. Эта панель отображает список шрифтов, установленных в системе, и позволяет выбрать название шрифта, его начертание и другие параметры.
Для управления диалоговой панелью Font в библиотеку классов MFC включен класс CFontDialog. Методы этого класса можно использовать для отображения панели Font и определения характеристик шрифта, выбранного пользователем. Конструктор класса CFontDialog:
Все параметры конструктора являются необязательными. Настройка стандартной панели выбора шрифта, которая выполняется конструктором класса CFontDialog по умолчанию, удовлетворяет большинству пользователей.
Параметр lplfInitial является указателем на структуру LOGFONT, описывающую логический шрифт. Если этот параметр используется, то в диалоговой панели по умолчанию будет выбран шрифт, наиболее соответствующий шрифту, описанному в структуре LOGFONT.
Параметр dwFlags задает набор флагов, управляющий различными режимами работы панели. Например, флаг CF_EFFECTS позволяет пользователю создавать подчеркнутые и перечеркнутые буквы, определять цвет букв, а флаг CF_SCREENFONTS - разрешает выбирать только экранные шрифты.
Через параметр pdcPrinter можно передать конструктору контекст отображения принтера, шрифты которого будут представлены в диалоговой панели Font. Данный параметр используется только в том случае, если в параметре dwFlags указаны флаги CF_PRINTERFONTS или CF_BOTH.
Через параметр pParentWnd можно указать родительское окно для диалоговой панели Font.
Методы класса CFontDialog
Для отображения диалоговой панели Font предназначен виртуальный метод DoModal. Если пользователь выбрал шрифт и нажал кнопку OK, метод DoModal возвращает идентификатор IDOK, если пользователь отменил выбор шрифта, метод DoModal возвращает идентификатор IDCANCEL:
Остальные методы класса предназначены для определения характеристик выбранного пользователем шрифта.
Метод GetCurrentFont позволяет сразу определить все характеристики выбранного шрифта, записав их в структуру LOGFONT.
Остальные методы класса позволяют определить только отдельные характеристики выбранного шрифта:
GetFaceName - Возвращает имя выбранного шрифта
GetStyleName - Возвращает имя стиля выбранного шрифта
GetSize - Возвращает размер выбранного шрифта
GetColor - Возвращает цвет выбранного шрифта
GetWeight - Возвращает плотность выбранного шрифта
IsStrikeOut - Определяет, является ли шрифт выделенным перечеркнутой линией
IsUnderline - Определяет, является ли шрифт выделенным подчеркиванием
IsBold - Определяет, является ли шрифт жирным
IsItalic - Определяет, является ли шрифт наклонным
Панель для вывода документов на печать (класс CPrintDialog)
Класс CPrintDialog можно использовать для создания двух видов диалоговых панелей, предназначенных для печати документов и выбора форматов документов. Кроме класса CPrintDialog можно также использовать класс CPageSetupDialog. Он позволяет создать диалоговую панель для выбора формата документа, имеющую несколько иной вид.
В приложениях, подготовленных с использованием средств MFC AppWizard и построенные по модели документ-облик, по умолчанию встроена возможность вывода редактируемого документа на печать.
В меню File такого приложения находятся три строки (Print, Print Preview и Print Setup), которые управляют процессом печати документов, подготовленных в приложении. Чтобы распечатать документ, достаточно выбрать из меню File строку Print. На экране появится диалоговая панель Print. В ней можно выбрать печатающее устройство для печати документов (группа Name), указать, будет печататься весь документ либо его часть (группа Print range), а также сколько копий документа будет напечатано (группа Copies). Также можно настроить различные характеристики печатающего устройства, если нажать кнопку Properties в группе Printer.
Если требуется определить только печатающее устройство и формат документа, из меню File следует выбрать строку Printer Setup. В группе Printer можно указать печатающее устройство и настроить его соответствующим образом. Группа Paper задает формат бумаги и режим подачи бумаги в печатающее устройство. Группа Orientation включает только один переключатель, определяющий ориентацию бумаги. Он принимает положение Portrait для вертикальной ориентации изображения на бумаге (режим "портрет") или Landscape для горизонтальной ориентации изоборажения на бумаге (режим "ландшафт").
Строка Print Preview меню File выбирается для предварительного просмотра документа перед печатью. При этом главное окно приложения изменит свой внешний вид и можно будет просмотреть, как будет выглядеть документ после печати.
Если не требуется выполнять специфическую обработку документа перед печатью, то вряд ли понадобится самостоятельное добавление программного кода, отвечающего за процесс печати. Просто следует отметить, что процедура создания панелей, связанных с печатью документа, практически ничем не отличается от создания выше описанных стандартных диалоговых панелей.
Панель для выполнения поиска и замены (класс CFindReplaceDialog)
Класс CFindReplaceDialog предназначен для управления диалоговыми окнами Find и Replace. Диалоговая панель Find используется для поиска известных строк в документе приложения, а панель Replace позволяет замену одной строки на другую.
Важным отличием диалоговых панелей Find и Replace от других стандартных диалоговых панелей является то, что они представляют собой немодальные диалоговые панели. Поэтому процесс создания этих панелей значительно отличается от процесса создания стандартных панелей для выбора цвета, шрифта и имен файла.