Иногда при работе с TreView контролом возникает очень неприятная проблема. Дело в том, что если размеры контрола небольшие, а названия нодов в нем длинные, то при использовании метода EnsureVisible для продвижения списка, ноды сдвигаются вправо, что очень неудобно. Решение этой проблемы не такое уж и простое. Этот пример демонстрирует как это можно сделать.
Вторая часть серии статей "Использование регулярных выражений в PHP" посвящена решению ряда проблем обработки сложных текстов с помощью "продвинутых" операторов регулярных выражений.
Несмотря на то, что термины данные и информация используются взаимозаменяемо, между ними есть существенная разница. Данные существуют реально. Данные — - это список температур, перечень недавних продаж или опись товара, имеющегося в наличии. Информация — это прогнозы. Информация — это предсказание погоды, прогноз прибылей и убытков и тенденции сбыта. Данные записываются в виде нулей и единиц, в то время как информация обрабатывается мозгом.
Между данными и информацией располагается приложение: механизм, который преобразует одно в другое и наоборот. Например, при покупке книги в Интернете это приложение преобразует вашу информацию — название книги, идентификатор, информацию о банковском счете — в данные: номер заказа, цену со скидкой, характеристики транзакции с использованием кредитной карточки и количество оставшихся в наличии экземпляров книги. Аналогичным образом, приложение преобразует данные в запрос на выборку со склада, отметку об отгрузке и номер отслеживания — информацию, необходимую для реализации продажи.
В действительности сложность создания приложения прямо пропорциональна преобразованиям, которые оно выполняет. Гостевая книга Web-сайта, передающая имя и адрес в поля базы данных, устроена элементарно. С другой стороны, онлайновый магазин, который передает большое количество видов информации в модель данных коммерческой сделки и преобразует данные в информацию для реализации процесса принятия решений, достаточно сложен с точки зрения разработки. Искусство программирования заключается в умелом манипулировании данными и информацией — мастерство, схожее с фиксацией света в живописи.
Как было сказано в первой части, регулярные выражения являются одним из самых мощных средств манипулирования данными. Регулярные выражения лаконично описывают форму данных и раскладывают их на составляющие. Например, следующее регулярное выражение можно использовать для обработки температуры, заданной в градусах по Цельсию или по Фаренгейту: /^([+-]?[0-9]+)([CF])$/.
Регулярное выражение сравнивает начало строки (отображается знаком "крышка" (^), за которым идет знак "+", знак "-", или ничего ([+-]?), за которым следует целое число ([0-9]+), обозначение шкалы — Цельсия или Фаренгейта ([CF]) — и заканчивается концом строки (обозначается знаком доллара $).
В данном регулярном выражении операторы начала строки и конца строки представляют собой примеры операторов нулевой ширины или совпадений по положению, а не по символам. Круглые скобки также не указывают на символы. Зато, если заключить шаблон в круглые скобки, то будет извлечен текст, соответствующий шаблону. Следовательно, если текст полностью сопоставим с шаблоном, то первая пара круглых скобок выдаст строку, представляющую собой положительное или отрицательное целое число, например, +49, а вторая пара круглых скобок - или букву C, или F.
В первой части серии представлено понятие регулярного выражения и были описаны PHP-функции для сравнения текста с шаблонами, а также для извлечения совпадений. А теперь давайте углубимся в изучение регулярных выражений и посмотрим на некоторые "продвинутые" операторы и средства.
Круглые скобки опять приходят на помощь
В большинстве случаев пара круглых скобок используется для описания части шаблона и получения текста, соответствующего этой части. Однако от круглых скобок не всегда требуется получение части шаблона. Как и в сложной арифметической формуле, круглые скобки можно использовать для группировки условий.
Приведу пример. Догадаетесь, какому типу данных соответствует данное выражение?
/[-a-z0-9]+(?:\.[-a-z0-9]+)*\.(?:com|edu|info)/i
Как можно догадаться, это регулярное выражение определяет имена Интернет-сайтов (только для доменов .com, .edu, и .info). Отличием является использование дополнительного оператора ?:. Квалификатор части шаблона ?: отключает функцию извлечения данных, и тем самым дает круглым скобкам возможность обозначать последовательность действий. Например, в данном случае фраза (?:\.[-a-z0-9]+)* соответствует нулю или более элементам строки, например, ".ibm." Аналогично, фраза \.(?:com|edu|info) обозначает последовательность символов, за которой идет одна из строк com, edu, или info.
Отключение функции извлечения информации может показаться бессмысленным, если не подумать о том, что извлечение информации требует дополнительной обработки. Если программа обрабатывает большое количество данных, то отказ от извлечения может быть целесообразным. Кроме того, если вы имеете дело со сложным регулярным выражением, то отключение функции извлечения информации в некоторых частях шаблона может упростить извлечение тех частей шаблона, которые реально нужны.
Примечание: Модификатор i в конце регулярного выражения делает все сопоставления с шаблоном нечувствительными к регистру. Следовательно, подмножество a-z будет сопоставимо со всеми буквами, независимо от регистра.
В PHP есть и другие модификаторы частей шаблона (subpattern). Используя отладчик регулярных выражений, показанный в первой части данной серии (повторно показан в листинге 1), попробуйте сопоставить регулярное выражение ((?i)edu) со строками "EDU," "edu," и "Edu." Если в начале части шаблона задать модификатор (?i), то сопоставление с шаблоном не будет зависеть от регистра. Чувствительность к регистру восстанавливается, как только заканчивается данная часть шаблона. (Сравните с модификатором / ... /i, который применяется ко всему шаблону.)
Листинг 1. Простой отладчик регулярных выражений
Еще один полезный модификатор части шаблона - это (?x). Он позволяет добавлять в шаблон пробелы, что упрощает чтение регулярных выражений. Таким образом, часть шаблона ((?x) edu | com | info) (обратите внимание на пробелы между операторами дизъюнкции, которые добавлены для удобочитаемости) аналогична (edu|com|info). Для того, чтобы добавлять пробелы и комментарии в регулярное выражение, можно использовать глобальный модификатор / ... /x, см. листинг ниже.
Листинг 2. Добавление пробелов и комментариев
Как видно из листинга, при необходимости модификаторы можно объединять. Если необходимо включить в регулярное выражение символ пробела при использовании модификатора (?x), используйте метасимвол \s для поиска любого пробельного символа и \ (обратный слеш с пробелом) для поиска одного пробела, например, ((?x) hello \ there).
Оглядываемся вокруг
В подавляющем большинстве случаев регулярные выражения используются для проверки или декомпозиции входной информации на отдельные "лакомые кусочки", которые записываются в архив данных или сразу же обрабатываются приложением. Общепринятыми сферами применения являются: обработка полей форм, парсинг XML-кода и анализ протоколов.
Еще одна область применения регулярных выражений - форматирование, нормализация или улучшение читаемости данных. Вместо того чтобы использовать регулярные выражения для поиска и извлечения текста, при форматировании они применяются для поиска и вставки текста в надлежащее местоположение.
Вот пример полезного применения форматирования. Предположим, что Web-форма передает приложению значение зарплаты с округлением до целого доллара. Так как зарплата хранится в виде числа целого типа, то перед сохранением переданных данных приложение должно удалять из них знаки пунктуации. Однако при извлечении данных из хранилища, возможно, понадобится изменить их формат и сделать удобочитаемыми с помощью разделителей. В листинге 3 показано, как простой PHP-запрос преобразует сумму в долларах в число.
Листинг 3. Преобразование суммы в долларах в число
Вызов функции preg_replace() заменяет знак доллара, любой пробельный символ и все запятые -- на пустую строку, возвращая то, что предположительно является целым числом. Если проверка функцией is_numeric() подтверждает правильность входных данных, их можно сохранить.
А теперь давайте выполним обратную операцию - добавим к числу знак денежной единицы и запятые-разделители сотен, тысяч и миллионов. Для добавления запятых в определенных позициях можно написать программу для поиска этих компонентов, а можно воспользоваться операторами посмотри вперед и посмотри назад. Модификатор части шаблона ?<= обозначает посмотри назад (то есть влево) от текущей позиции. Модификатор ?= означает "посмотри вперед" (то есть вправо) от текущей позиции.
[pagebreak]
Итак, какие позиции нам нужны? Любое место в строке, при условии, что есть как минимум один символ слева и одна или более групп по три символа справа, не считая десятичной точки и количества центов. Соблюдая это правило и используя два модификатора, анализирующих символы справа и слева от определенной позиции и являющихся операторами нулевой ширины, мы можем достичь цели с помощью следующей инструкции:
Как работает это регулярное выражение? Начиная с первого символа строки и обрабатывая каждый символ, регулярное выражение отвечает на вопрос: "Есть ли хотя бы один символ слева и одна или несколько групп из трех символов справа?" Если да, то наш оператор нулевой ширины заменяется запятой.
Большинство сложных сопоставлений можно реализовать, используя стратегию, аналогичную приведенной выше. Например, вот еще один вариант использования оператора "посмотри вперед", который решает широко распространенную дилемму.
Листинг 4. Пример использования оператора "посмотри вперед" ("предвидение")
Оператор preg_replace() преобразует строку данных, разделенных запятыми, в строку данных, разделенных знаком табуляции. Предусмотрительным образом, он не заменяет запятые в строке, заключенной в кавычки.
Это регулярное выражение при каждом обнаружении запятой (на это указывает запятая в самом начале регулярного выражения) проверяет утверждение: "Впереди не было кавычек или было четное количество кавычек". Если утверждение верно, то запятую можно заменить знаком табуляции (the \t).
Если Вам не нравятся операторы «посмотри вперед» и «посмотри назад» или вы работаете с таким языком, в котором их нет, можно добавить запятые в число и с помощью обычного регулярного выражения. Однако для реализации такого решения потребуется много итераций.
Листинг 5. Добавление запятых
Давайте пройдем по коду. Сначала параметр зарплаты очищается от знаков пунктуации для моделирования ситуации чтения целого числа из базы данных. Затем выполняется цикл в поисках позиций, где за одним числовым символом ((\d) идут три числовых символа ((\d\d\d\): если обнаруживается граница слова, заданная как \b, цикл прекращается. Граница слова -- это еще один оператор нулевой ширины, который соответствует следующим позициям:
* Перед первым символом строки, если это буква слова.
* За последним символом строки, если это буква слова.
* Между буквой слова и небуквенным символом, непосредственно за буквой слова.
* Между небуквенным символом и буквой слова, непосредственно за небуквенным символом.
Таким образом, примерами правильных границ слова являются пробел, точка и запятая.
Благодаря внешнему циклу регулярное выражение перемещается слева направо в поисках цифры, за которой идут три цифры и граница слова. При обнаружении совпадения между двумя частями шаблона добавляется запятая. Цикл должен продолжаться до тех пор, пока оператор preg_replace() находит совпадения, что задано в условии $old != $pretty_print.
Жадность и лень
Регулярные выражения обладают большими возможностями, иногда даже слишком большими. Например, давайте рассмотрим, что произойдет, если регулярное выражение ".*" будет обрабатывать строку "The author of 'Wicked' also wrote 'Mirror, Mirror.'" Вероятно, вы предполагаете, что preg_match() вернет два совпадения, и с удивлением обнаружите, что результат всего один: 'Wicked' also wrote 'Mirror, Mirror.'
Почему? Если не задать иное, то такие операторы как * (ноль или более) и + (один или более) -- "жадные". Если сопоставление с образцом может продолжаться, то они и будут его продолжать до тех пор, пока не будет возвращен максимальный результат из возможных. Для сохранения минимальных совпадений необходимо принудительно заставлять определенные операторы быть "ленивыми". "Ленивые" операторы находят самое короткое совпадение и на этом останавливаются. Чтобы сделать оператор более "ленивым", добавьте суффикс в виде знака вопроса. Пример показан в листинге 6.
Листинг 6. Добавление суффикса в виде знака вопроса
Регулярное выражение ".*?" расшифровывается следующим образом: "найти кавычку, за которой идет ровно столько символов с последующей кавычкой.
Однако иногда оператор * может быть слишком "ленивым". Например, посмотрите на следующий фрагмент кода. Что он делает?
Листинг 7. Простой отладчик регулярных выражений
Что вы загадали? "123"? "1"? Нет результата? На самом деле результатом будет Array ( [0] => [1] => ), означающий, что совпадение было найдено, но никаких данных извлечено не было. Почему? Вспомните, что оператор * ищет совпадения с нулем или более символов. В данном случае, выражение [0-9]* находит совпадение с нулем символов от начала строки, и обработка заканчиваетс.
Для решения данной проблемы добавьте оператор нулевой ширины для привязки совпадения, который заставляет регулярное выражение продолжать сопоставления; /([0-9]*\b/.
Советы и рекомендации
С помощью регулярных выражений можно решать как простые, так и сложные задачи при обработке текста. Начните с небольшой группы операторов и по мере того, как вы будете набираться опыта, расширяйте свой словарь. В качестве вознаграждения за ваши старания -- некоторые советы и рекомендации.
Создание переносимых регулярных выражений с помощью классов символов
Вам уже знакомы метасимволы, например, \s - соответствует любому пробельному символу. Кроме того, большинство реализаций регулярных выражений поддерживает предопределенные классы символов, которые более просты в использовании и переносимы с одного письменного языка на другой. Например, класс символов [:punct:] замещает все символы пунктуации в данном языке. Вместо [0-9] можно использовать [:digit:] и более переносимое замещение [:alpha:] вместо [-a-zA-Z0-9_]. Например, можно убрать все знаки пунктуации, используя:
Класс символов представляет собой более сжатую форму по сравнению с подробным описанием всех символов пунктуации. Полный перечень классов символов можно найти в документации по версии языка PHP.
Как исключить то, что вы не ищете
Как показано в примере с данными, разделенными символом табуляции, в качестве значений, разделенных запятыми (CSV), иногда проще и точнее задать список тех вариантов, которые не нужно находить (сопоставлять). Последовательность, начинающаяся со знака "крышка" (^) будет соответствовать любому символу, не принадлежащему данной последовательности. Например, для проверки правильности телефонных номеров для США можно использовать регулярное выражение /[2-9][0-9]{2}[2-9][0-9]{2}[0-9]{4}/. Используя набор ограничений можно написать регулярное выражение в более явном виде /[^01][0-9]{2}[^01][0-9]{2}[0-9]{4}/. Оба регулярных выражения работают, хотя смысл последнего, вероятно, более понятен.
Пропуск новой строки
Если во входных данных несколько строк, стандартного регулярного выражения будет недостаточно, так как сканирование прекращается на начале новой строки, которая обозначается $. Однако, если воспользоваться модификаторами s или m, то регулярное выражение будет обрабатывать входные данные по-другому. Первый модификатор рассматривает строковую последовательность как одну строку, где точка указывает на начало новой строки (обычно она этого не делает). Второй рассматривает строковую последовательность как несколько строк, где ^ и $ соответствуют началу и концу любой строки, соответственно. Приведем пример. Если задать $string = "Hello,\nthere";, то оператор preg_match( "/.*/s", $string, $matches) параметру $matches[0] присвоит значение Hello,\nthere. (При удалении s будет выдано Hello.)
Последний представленный компанией Microsoft продукт семейства Windows 2003 - является прямым продолжением Windows 2000. Эта система предназначена, в основном, для серверного, а не для домашнего использования. Но некоторое количество усилий и грамотный тюнинг системы позволят превратить домашний компьютер в стабильный мультимедийный игровой сервер.
Практически ежегодно Microsoft представляет публике новую версию самого популярного своего продукта - операционной системы Windows. По традиции компания обещает, что именно эта, последняя версия наиболее стабильна, надежна и удобна. Все по той же традиции пользователи ждут "улучшений" с изрядной долей пессимизма…
Конечно, идеальной операционной системы не существует, и семейство Windows имеет как плюсы, так минусы. Однако, положа руку на сердце, признаем: прогресс, в первую очередь в стабильности, есть. Кроме того, следует учитывать, что продукцией Microsoft пользуются десятки миллионов пользователей во всем мире - и угадать конфигурацию компьютера, индивидуальные потребности к внешнему оформлению и набору программ просто невозможно. Поэтому, установив Windows на свой ПК, не рассчитывайте, что дальше система будет работать идеально - она будет работать стандартно, в расчете на среднестатистические потребности пользователя.
Семейство Windows 2003 Server (Standard, Enterprise, Web и Datacenter Edition) является прямым продолжением Windows 2000 Server. В отличие от Windows ХР, которая является гибридом Windows Ме и Windows 2000, новая система предназначена, в основном, для серверного, а не для домашнего использования. Соответственно, многие функции, присущие "домашнему" компьютеру… исчезли. Но небольшое количество усилий, грамотный тюнинг системы - и стабильный мультимедийный игровой сервер к вашим услугам!
Установка драйверов
Установка системы практически идентична инсталляции Windows ХР, поэтому не будем на ней останавливаться - основные трудности впереди.
Первое, с чем сталкивается пользователь после установки Windows 2003 Server, это отсутствие драйверов под эту версию Windows. По умолчанию большинство устройств на вашем компьютере будет работать, но… например, видеокарта без 3D-функций в наше время мало кого заинтересует.
Первый делом следует создать нового пользователя. Для этого нажимаем на кнопку Start (Пуск) и выбираем подменю Run (Выполнить). Далее вводим команду lusrmgr.msc - и попадаем в программу User Management (Управление пользователями). Правой клавишей мышки кликаем на папке User (Пользователи) в левой части окна и выбираем меню New User (Новый пользователь). Прописываем имя пользователя и, при желании, пароль. Подтверждаем создание и после этого выбираем - при помощи правой клавиши мыши - Properties (Свойства) нового пользователя. Переходим на вкладку Member of (Участник группы), нажимаем кнопку Add (Добавить), далее Find Now (Найти) и дважды кликаем на Administrators (Администраторы).
Итак, новый пользователь с правами администратора создан, остается перезагрузиться под новым логином.
Кстати, просто так перезагрузить и даже просто выключить компьютер уже не удастся. На экране появится окно, в котором система попросит указать причину перезагрузки/выключения. Зачем это нужно? Отвечать на этот вопрос предоставим компании Microsoft, а сами тем временем зайдем в уже знакомое пусковое меню и в подменю Run… (Выполнить) введем команду mmc. Выбираем меню File (Файл), а в нем Add/Remove Snap-in… (Добавить / Убрать Snap-in…). Далее следуем по пунктам меню: Add, Group Policy Object Editor, Add. После этого нажимаем кнопку Finish (Завершить). Переходим в Local Computer Policy > Computer Configuration > Administrative Templates - и выбираем папку System. Дважды кликаем на Display Shutdown Event Tracker. В появившемся меню выбираем Disabled, нажимаем и выходим из программы. Теперь перезагрузка/выключение компьютера буде проходить аналогично Windows 2000.
После того как система загружена под вновь созданным логином, следует приступить к настройке драйверов. Для этого необходимо зайти в Desktop Properties (Свойства экрана) с помощью Control Panel (Панели управления): Пуск > Панель управления > Display (Экран).
Далее переходим на последнюю вкладку - Advanced (Дополнительно) и нажимаем кнопку Troubleshoot (Неисправности). В появившемся меню передвигаем ползунок Hardware Acceleration (Аппаратное ускорение) максимально вправо. Закрываем окна и устанавливаем драйвера под видеокарту. Теперь система не будет выдавать ошибку о несовпадении версии драйвера и Windows. Кстати, для установки подходят драйверы как Windows ХР, так и Windows 2000.
По умолчанию в Windows 2003 Server установлен DirectX 8.1, но отключена поддержка 3D-функций. Кстати, самой папки DirectX в Programs Files (Программные файлы) нет, поэтому следует ввести команду dxdiag в подменю Run… (Выполнить). Открывается окно DirectX, где на вкладке Display (Экран) необходимо включить (нажать кнопки Enabled) функции аппаратного ускорения.
По мнению специалистов компании Microsoft, для полноценной работы сервера звук не обязателен. Соответственно, звуковые функции вашего компьютера по умолчанию будут отключены. В Панели управления есть вкладка Administrative Tools (Средства администрирования), внутри которой выбираем Services (Службы). В появившемся окне размещен список служб, установленных на ПК. Некоторые из них не включены, в том числе и Windows Audio. Дважды кликаем мышкой - и в появившемся окне, в поле Startup type (Способ загрузки), выбираем Automatic, нажимаем Start (Запустить). При необходимости следует выбрать в Панели управления раздел Sound and Audio Devices (Мультимедийные устройства) и в появившемся окне включить громкость звука (перетащить ползунок в крайнее правое положение).
Изменение внешнего вида
Сразу после установки Windows 2003 Server будет иметь спартанский вид (как Windows 2000). Единственное отличие: стартовое меню, частично схожее с Windows ХР. Это практично, удобно, выгодно с точки зрения экономии ресурсов - в общем, прекрасно подходит для сервера, где вид рабочего стола - далеко не самое главное. Однако на домашнем компьютере хочется видеть нечто более яркое, чем стандартные окна Windows.
Возможность преобразовать внешний вид в стиль Windows ХР есть - хотя и скрыта в недрах системы. В первую очередь необходимо включить службу Themes. Для этого заходим в службы (Control Panel > Administrative Tools > Services) и дважды кликаем на службе Themes. В появившемся окне выбираем тип запуска Automatic (Автоматически) и перезагружаем компьютер. После перезагрузки заходим в свойства экрана, кликнув для этого правой клавишей мыши на рабочем столе и выбрав пункт Properties (Свойства). На вкладке Themes выбираем вместо темы Windows Classic тему Windows XP. Теперь рабочий стол и окна приложений приобретут знакомый стиль Windows ХР.
Кроме того, в свойствах системы (Control Panel > System) на вкладке Advanced в разделе Visual Effects есть возможность дополнительной настройки визуальных эффектов Windows.
Десять шагов к идеальной системе
1. Одно из последних усовершенствований системы - параметр prefetch. Его задача заключается в ускорении загрузки приложений. Включение этого параметра не влияет на скорость слишком ощутимо, однако в бою все средства хороши. Для включения этого параметра кликните правой клавишей мыши на ярлыке нужной программы и выберите в появившемся меню пункт Properties (Свойства). В строке Object (Объект) после указания пути к файлу добавьте /prefetch:1 (пробел перед ключом обязателен).
2. Перейдите к закладке Advanced (Дополнительно) в Performance Options (Параметрах быстродействия) и убедитесь, что распределение ресурсов процессора и памяти выставлено на оптимизацию работы Programs (Программ) - указывать приоритет фоновых служб и кэша необходимо, только если ваш компьютер выполняет роль сервера. В опции Memory usage при объеме физической памяти 256 Мб и выше отметьте параметр System cache. Если же памяти на компьютере меньше 256 Мб, система будет работать быстрее при установленном значении Programs.
3. Проверим правильность настройки жесткого диска. В свойствах системы откройте Device Manager (либо, открыв свойства любого диска в Проводнике, закладка Hardware) и просмотрите свойства вашего жесткого диска. Убедитесь, что в закладке Polices стоит отметка Enable write caching on the disk. Если диск SCSI доступны следующие значения в закладке SCSI Properties: Disable Tagged Queuing и Disable Synchronous Transfers должны быть не отмечены.
4. Убедитесь, что DMA включено для всех IDE-устройств системы. Проверить это можно следующим образом: Device Manager > IDE ATA/ATAPI controllers > Primary/Secondary IDE Channel > Advanced Settings. Параметр Device Type позволяет системе автоматически определять подключенные устройства (если канал свободен, установите значение None - это немного ускорит загрузку системы).
Параметр Transfer mode Windows ставит, как правило, по умолчанию и позволяет Windows использовать максимальный DMA, поддерживаемый устройством либо PIO, убедитесь, что значение установлено DMA if available.
5. Для ускорения навигации по папкам, содержащим графические файлы, можно отметить пункт Do not cash thumbnails (Не кэшировать эскизы). Для этого следует зайти в Control Panel (Панель управления) > Folder Options (Свойства папки) > View (Вид), а заодно убрать "галочку" с пункта Remember each folder`s view setting (Помнить параметры отображения каждой папки).
6. Поиск в Windows 2003 Server по умолчанию производится и в.zip-архивах. Скорость поиска возрастет, если отключить эту службу. Для этого в командной строке необходимо набрать:
Код:
или же:
Код:
Для включения поиска в.zip-архивах:
Код:
или же:
Код:
7. В отличие от более ранних версий Windows, в процессе установки Windows 2003 Server нет возможности выбирать необходимые компоненты. Удалить/установить можно лишь незначительную часть программ (Control Panel > Add or Remove Programs > Add/Remove Windows Components). Список невелик - большая его часть скрыта от глаз неопытного пользователя.
Для решения этой проблемы открываем системную папку Inf (по умолчанию - C:WindowsInf), находим в ней файл sysoc.inf, открываем его и удаляем во всех строках слово HIDE. Главное при этом - оставить неизменным формат файла, то есть следует удалять только HIDE, оставляя запятые до и после этого слова.
Для примера - исходная строка и та, что должна получиться:
Код:
Сохраняем файл sysoc.inf, открываем Add/Remove Windows Components - и видим уже значительно более длинный список.
8. Служба индексирования создает индексы содержимого и свойств документов на локальном жестком диске и на общих сетевых дисках. Имеется возможность контроля за включением сведений в индексы. Служба индексирования работает непрерывно и практически не нуждается в обслуживании. Однако процесс индексирования потребляет большое количество ресурсов процессора. Если вы не пользуетесь активно поиском по контексту файлов, данную службу можно отключить. Для этого заходим в Control Panel (Панель управления) > Add or Remove Programs (Установка и удаление программ) - Add/Remove Windows Components (Установка компонентов Windows). В появившемся списке ищем Службу индексирования и убираем "галочку".
9. Если вам не нравятся "излишества" в новом оформлении XP или конфигурация вашего компьютера не позволяют вам ими наслаждаться, интерфейс можно вернуть к "стандартному" виду. Для этого необходимо зайти в Control Panel (Панель задач) > System (Система) и перейти на вкладку Advanced (Дополнительно). Выбираем раздел настройки визуальных эффектов.
10. Довольно часто у домашнего компьютера только один пользователь, так что необходимости в пароле при запуске системы нет. В отличие от предыдущих версий, в этой Windows 2003 пароль убрать не так-то просто.
В процессе загрузки можно пропустить выбор имени пользователя и набор пароля. Выберите Run… (Выполнить) из меню Start (Пуск) и наберите control userpasswords2, что приведет к открытию окна User Accounts (Учетные записи пользователей). На вкладке Users (Пользователи) удалите флажок у позиции Users must enter a user name and password to use this computer (Требовать ввода имени пользователя и пароля). После подтверждения появится диалоговое окно, в котором система предложит ввести имя пользователя и пароль для нужной учетной записи.
Итак, что нам понадобится. В первую очередь - 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С".
В данной статье рассмотрены принципы, помогающие компилятору Delphi генерировать более оптимальный с точки зрения скорости код. Если Вы не хотите вникать в подробности, в конце статьи есть «свод правил», которые рекомендуется соблюдать при написании программ.
Компилятор Delphi относится к разряду оптимизирующих. Но насколько качественно проводится оптимизация? Как «помочь» компилятору создать более быстрый код? Давайте разберемся с этим на экспериментах.
Оптимизация константных выражений
Пример 1:
С точки зрения оптимизации код можно упростить еще на этапе компиляции до
Но написанный выше листинг преобразуется в
С одной стороны компилятор не «сообразил», что значение переменной «a» можно преобразовать в константу и сложить с другой константой (которая, заметим, подставлена именно как константа) на этапе компиляции, с другой стороны был применен весьма хитрый трюк с LEA (об этом ниже). Тем не менее, код
в любом случае быстрее и короче.
Пример 2:
Скомпилированный код будет выглядеть
А ведь значение, присвоенной переменной «а» являлось константой и наш пример можно было бы переписать как:
Пример 3:
После компиляции получаем:
Т.е. компилятор преобразовал код так, как он был написан, а ведь можно было бы просто записать:
Оптимизация алгебраических выражений
Пример 4:
После компиляции эти переменные будут удалены, причем с предупреждением
Пример 5:
Код скомпилируется как есть! Таким образом мы обманули компилятор псевдо использованием переменных. Delphi не исправляет нашей «кривости», поэтому эта задача ложится исключительно на плечи программиста.
Пример 6:
Данный код можно оптимизировать до
И этого Delphi за нас не сделает.
Пример 7:
В данном примере первую строчку можно безболезненно удалить, что Delphi делать умеет.
Пример 8:
В данном случае можно избавится от одной операции умножения, присвоив значение выражения a*b временной переменной. Анализ ассемблерного листинга показывает, что компилятор именно так и поступает. Тем не менее, поменяв второе подвыражение на ((b*a)>0), компилятор принимает выражения за разные и генерирует умножение для обоих случаев, не смотря на то, что результат одинаков.
Оптимизация арифметических операций
Сложение и вычитание
Применение инструкции LEA вместо ADD позволяет производить сумму 3х операндов (двух переменных и одной константы) за один такт. Трюк заключается в том представление ближних указателей эквивалентно их фактическому значению, поэтому результат, возвращенный LEA равен сумме ее операндов. При возможности Delphi производит такую замену.
Деление
Операция деления требует гораздо больше тактов процессора, нежели умножение, поэтому замена деления на умножение может значительно ускорить работу. Существуют формулы, позволяющие выполнять такое преобразование. Тем не менее, Delphi не использует такую оптимизацию. Деление на степень двойки можно заменять сдвигом вправо на n бит, но даже в этом случае получаем следующий код:
Здесь учитывается особенность самой операции div – округление в большую сторону. Поэтому, если можно пренебрегать округлением, используйте c:=a shr 1 вместо с:=a div 2.
Умножение
Умножение на степень двойки можно заменять сдвигами битов. Delphi заменяет умножение сдвигами при умножении на 4,8,16 итд. При умножении на 2 производится суммированием переменной с собой.
Умножать на 3,5,6,7,8,10 и т. д. можно и без операции умножения – расписав выражение по формуле (a shl n)+a, где n – показатель степени двойки. Например, при умножении на 3 n=1. Delphi при возможности прибегает к этому трюку. Заметим, операнд LEA умеет умножать регистр на 2,4,8, что также при возможности используется компилятором. Например, умножение на 3 преобразуется в инструкцию
Оптимизация case of
Анализ скомпилированного кода показывает, что Delphi проводит утрамбовку дерева. Т.е. значения case сортируются и выбор нужного элемента производится при помощи двоичного поиска.
В случае, если элементы case of выстраиваются в арифметической прогрессии, компилятор формирует таблицу переходов. Т.е. создается массив указателей с индексами элементов, поэтому выбор нужно элемента выполняется за одну итерацию независимо от количества элементов.
Оптимизация циклов
Разворачивание циклов – не производится. Разворачивание циклов весьма спорный момент в оптимизации, поэтому принять грамотное решение может только человек. Delphi не производит разворачивания ни больших, ни маленьких циклов.
Слияние циклов – не производится. Если два цикла, следующие друг за другом имеют одинаковые границы итерационной переменной, разумно оба цикла объединить в один.
Вынесение инвариантного кода за пределы цикла – не выносится. Наиболее распространенный недочет – условие цикла записывается как:
Delphi будет при каждой итерации вызывать метод count, вычитать из результата 1 и потом уже сверять. Настоятельно рекомендуется переписывать подобный код как
Весь код VCL написан с нарушением этого правила. Очевидно, что проще подобного рода оптимизацию встроить в компилятор, нежели переписывать VCL :)
Замена циклов с предусловием на циклы с постусловием – производится. Циклы с постусловием имеют главное преимущество над другими видами циклов (с предусловием и с условием в середине) – они содержат всего одно ветвление. Delphi производит такую замену.
Замена инкремента на декремент – не производится. Более того, даже декрементный цикл компилируется в неоптимальный код, т.к. не используется флаг ZF. Вместо этого происходит сравнивание значения регистра с 0.
Удаление ветвлений – не производится.
Вывод:
1. Не используйте переменные для временного хранения констант или обязательно объявляйте «магические» числа как const, либо подставляйте в код непосредственные значения
2. Неиспользуемыми объявлениями и присвоениями можно безболезненно пренебрегать – Delphi умеет их вычищать.
3. Внимательно следите за использованием переменных, в частности лишним присвоениям их значений друг другу. Такого рода оптимизации Delphi делать не умеет.
4. Используйте свернутые математические выражения. (например, (3*a - a) /2 упрощается до a). Delphi не умеет упрощать математические выражения. (Да и что говорить, даже MathCAD не всегда грамотно умеет делать такие преобразования).
5. Не используйте конструкции типа a:=10*sin(45*pi/180); Delphi не вычислит эту константу на этапе компиляции, напротив, будет послушно вызывать sin и pi по ходу выполнения программы! В случае, если угол является переменной, по крайней мере pi можно заменить константой 3,1415...
6. Delphi прекрасно справляется с выражениями, полностью составленных из констант – они вычисляются на этапе компиляции.
7. Внимательно следите за условиями и их границами. Компилятор Delphi не умеет обнаруживать заведомо ложных условий. Также он не умеет удалять заведомо лишние условия. Например, (a>0) and (a<15616) and (a<>0)
8. Если в условии несколько раз проверяется одно и тоже выражение, следите, чтобы оно было выражено во всех конструкциях одинаково. В противном случае скомпилированный код будет не оптимален. Например, if ((a*b)>0) and ((a*b)<1024) then... При перестановке во втором случае b*a смысл выражения не изменится, но код будет иметь уже на одну операцию умножения, а две. Можно временно присвоить проверяемое выражение временной переменной, а затем уже проверять полученное значение.
9. Сообщение «Combining signed and unsigned types – widened both operands» сообщает не только о потенциальной ошибке – также вследствие преобразования мы теряем производительность. Например, z – объявлена как ineteger. условие if z>$abcd6123 then z:= $abcd6123; несмотря на его правильность вызовет данное предупреждение. Сгенерированный код будет, выполнять преобразования величин до 64-х бит, и дальнейшее уже сравнение 64-х битных операндов. Если изменить тип z на cardinal, мы избавимся от предупреждения и получим 3 строки кода, вместо 8 !
10. Delphi умеет оптимизировать сложение, умножение и частично деление. При делении на степень двойки, если не важно округление до большего, рекомендуется пользоваться shr 1 вместо div 2.
11. В case of при возможности используйте элементы, расположенные в арифметической прогрессии. Тем не менее, даже при невыполнении данного условия мы получим качественный код после утрамбовки дерева.
12. Выносите инвариантный код за тело цикла. Наиболее частая ошибка – for i:=1 to length(str) do... Дело в том, что при каждой итерации будет вызываться функция length, что пагубно скажется на производительности. Рекомендуется длину строки заранее присвоить переменной. Также не включайте в тело цикла код, заведомо не зависящий от изменения итерационной переменной.
Сравнивая Delphi с компиляторами Visual C++, WATCOM, Borland C++ (тестирование данных компиляторов приведено в [1]) приходим к выводу, что Delphi по своим оптимизирующим свойствам аналогичен Borland C++ (а кто сомневался? ;) ). Учитывая, что Borland C++ по итогам сравнения оказался последним, делаем несложный вывод. Весьма печален и тот факт, что большинство кода VCL написано с точки зрения «красоты» кода, а не его оптимальности с точки зрения скорости. Например, не соблюдается правило 12.
Эта статья не инструкция по изготовлению фальшивых печатей. Здесь пойдёт речь о том, как нарисовать макет, из которого можно будет сделать настоящую печать. Изготавливается она путем вырезания клише из специальной пластмассы. Так как клише вырезается в макете не должно быть видимых контуров - только заливки, а то лазерный резец пройдёт два раза и испортит заготовку.
Рисуем Круглую Печать.
Эта статья не инструкция по изготовлению фальшивых печатей. Здесь пойдёт речь о том, как нарисовать макет, из которого можно будет сделать настоящую печать. Изготавливается она путем вырезания клише из специальной пластмассы. Так как клише вырезается в макете не должно быть видимых контуров - только заливки, а то лазерный резец пройдёт два раза и испортит заготовку.
И так начинаем рисовать.
1. Рисуем окружность с нажатым Ctrl - так она получится окружностью, а не эллипсом.
Назначаем (не снимая выделения, на панели опций) нужный размер нашей окружности - к примеру, 50 миллиметров. Дублируем (Ctrl+D) или копируем (Ctrl+C, Ctrl+V) окружность. Нам нужно учесть толщину будущего внешнего контура печати - скажем, его толщина должна быть 2 миллиметра. Соответственно, нам нужно вычесть ее из диаметра второй окружности. Не забывайте, что вычитать нужно двойное число (толщина контура 2 мм - уменьшаем диаметр второй окружности на 4 мм, т.е. 2 мм с одной стороны от центра, и 2 мм с другой). Теперь инструментом "Указатель" выделяем обе окружности (или "рамкой", не отпуская левую кнопку мыши, охватываем полностью обе окружности, или с нажатым Shift щелкаем по очереди на каждой). Включаем "Выравнивание и распределение" - и выравниваем объекты относительно друг друга по центру (по вертикали и по горизонтали).
2. Теперь нам необходимо превратить две окружности в один объект. Не снимая с них выделения, жмем Combine (Ctrl+L) на панели опций. У нас получится кольцо из двух окружностей.
Можно обойтись и без Combine - задать контур необходимой толщины, а за тем превратить его в объект (Arrange/Convert To Object). Здесь важно помнить (и учитывать при макетировании), что контур размещается по обе стороны реального абриса объекта - 4-миллимитровый, к примеру, выступает наружу на 2 мм и настолько же углубляется в сам объект.
3. Пункт специально для самых новичков. Если Вы помните, говорилось о полном отключении контуров и оставлении в макете ТОЛЬКО заливок. Если кто не знает, как это сделать, вот: Быстрое отключение контура - выделив необходимый объект, жмем правой кнопкой мыши СЮДА (выделено на картинке).
или то же самое (такую же кнопку) жмем на панели инструментов в параметрах контура:
4. Часто в центре печати размещается какое-либо изображение - герб, логотип, знак, текстура. Здесь главное, чтобы рисунок был ВЕКТОРНЫМ. И обязательно - одноцветным, контрастным, без полутоновых переходов. Следовательно, растровую картинку (если другой не имеется) необходимо или подвергнуть трассировке, или нарисовать заново (ВНИМАНИЕ!!! после трассировки обязательно подчищайте и дорабатывайте бывший растр, чтобы максимально уменьшить количество узловых точек и сгладить кривые). Можно использовать заливку монохромным узором или узором PostScript:
можно использовать (как в этом примере) докер "Вставить символ":
однако, не стоит столь откровенно пользоваться встроенными девайсами. Хороший дизайнер нарисует сам и свою собственную картинку.
5. Выравниваем все объекты - и окружности, и центральную картинку - так же, как выравнивали в самом начале, в пункте 1. И теперь, во избежание случайного сдвига элементов будущей печати, надо заблокировать все элементы:
Блокировка хороша тем, что сами заблокированные объекты никуда не денутся до отмены блокировки, а вот такая опция, как текст, пущенный "по пути", с заблокированными кривыми запросто проделывается.
6. Выбираем инструмент "текст", подносим к внешней окружности - контуру печати. Щелкаем левой кнопкой мыши тогда, когда курсор выглядит, как буква А, лежащая на волнистой линии (пустить текст "по пути"), а не как буквы АВ, замкнутые в рамку (параграфный текст - объект станет "рамкой" для текстового блока). Пишем необходимую надпись - шрифт и размер настраиваем по усмотрению (или по желанию заказчика). Написанную строчку необходимо выровнять:
не снимая выделения с текста, выберите инструмент "указатель" - и можете перемещать текстовую строку интерактивно, зажав, красный ромбовидный маркер левой кнопкой мыши. Или пошагово сдвигайте строчку, нажимая команды на панели опций - красным обведен "сдвиг вдоль пути", оранжевым - "оторвать от пути" (вверх-вниз).
ВНИМАНИЕ! в 12 версии инструментом "указатель" можно совершить интерактивный сдвиг только ВДОЛЬ пути, а в 13 версии Корел интерактивно не только можно двигать текст вдоль пути, но и отрывать от пути. Плюс еще работает и выравнивание по центру:
7. Нижняя строка (если это отдельная строка) должна читаться без "выворачивания" головы, как в обычном тексте - смысл в том, что верхняя строчка просто дугообразно изгибается вверх, а нижняя - вниз. Пишем строчку, как в пункте 6, но мысленно ее "переворачиваем". После написания строчки жмем СЮДА:
Выравниваем так же, как в пункте 6. Обращаю внимание пользователей 12 и 13 версии Корел: в 12 версии эта кнопка только ОДНА, активна она при выделении текста, идущего по пути, ИНСТРУМЕНТОМ "УКАЗАТЕЛЬ". На панели опций это крайняя справа кнопка. Она просто размещает надпись с другой стороны пути. В 13 версии эту опцию завязали с принципом "отражения". Поэтому необходимо нажать ОБЕ кнопки, показанные на скриншоте, если вы не хотите, чтобы надпись осталась зеркальной.
Еще один важный момент: межбуквенное расстояние в тексте, пущенном "по пути", так или иначе искажается. Здесь - в верхней строчке буквы слегка "разъехались", а в нижней - слишком придвинулись друг к другу. Для коррекции можно выбрать инструмент "форма" и потянуть за выделенный на скриншоте маркер: влево - межбуквенное расстояние сокращается, вправо - увеличивается. Можно так же чуть сдвинуть отдельные буквы, если они визуально "отваливаются" от основного текстового блока или, напротив, "прижимаются" друг к другу.
Можно еще добавить декоративные элементы - точки, полосы, звездочки - на "стыке" верхней и нижней надписи.
В конце работы необходимо проверить соответствие макета техническим требованиям конкретного предприятия, которое будет изготавливать печать. Говоря простым языком - существует некая "минимальная толщина" линии, которую способна воспроизвести та или иная аппаратура. Эту толщину необходимо выяснить заранее. Проверка делается элементарно - всей печати назначается контрастная (красная, к примеру) обводка, где толщина контура - тот самый "минимум". Если контур не пересекает сам себя и не наезжает на другие элементы макета - работа выполнена корректно. В противном случае необходимо вносить исправления. Необходимый минимум - это толщина самих элементов и промежутков между ними, о чем тоже важно помнить. Еще очень важно - чтобы отдельные элементы печати не пересекали друг друга.
Да - если вместо двух строчек текста идет одна длинная (типа - "младший помощник старшего дворника по уборке самых противных помещений"), то в этом случае "выворачивание головы" не страшно - подобный текст пишется одной строкой по кругу.
ОБЯЗАТЕЛЬНО - при сдаче макета на изготовление, превратите все объекты (особенно это касается текста) в кривые, или приложите к макету файлы с использованными шрифтами.
В этой статье описываются полезные функции и процедуры, помогающие эффективно работать с различными типами данных в системе "1С:Предприятие 7.7".
Форматирование данных в 1С
Список значений в 1С
Таблица значений в 1С
Таблица или печатная форма в 1С
Периоды и даты в 1С
Календари и праздники в 1С
[pagebreak]
Справочники в 1С
Документы в 1С
Предопределённые функции и процедуры в 1С
Налоговый учёт и первое событие в 1С
Резюме
В статье описаны функции и процедуры, используемые в программе "1С:Предприятие 7.7" для работы со справочниками, документами, списками значений, таблицами значений и с прочими агрегатными типами данных. Образцы практического применения описанных средств Вы сможете найти в статьях "Отчёты для 1С" и "Обработки для 1С".
В приведенном ниже примере описано как можно получить список логических дисков, установленных в системе, а также определить их тип. Для этих целей используются функции winAPI GetLogicalDrives и GetDriveType.
Для работы примера на форму проекта поместите объекты Button1 и Memo1. В обработчике событий для Button1 нужно ввести указанный код.