понедельник, 23 ноября 2009 г.

Статистика использования компонентов

Статистика использования компонентов

Задался я тут как-то вопросом: а какие компоненты я использую чаще всего? Вопрос, конечно, интересный, но как это подсчитать? Вручную открывать схемы и считать - глупейшее занятие, потому что и за год, наверное, не пересчитать. И решил я сделать программу.

Если вам тоже интересно, какие компоненты вы используете чаще всего, то читайте дальше, я буду показывать создание программы. Но сначала определимся: что должна уметь программа? Конечно, собирать сведения о компонентах в файлах sha и представлять их таблице с количеством использованных.

Очень важно знать состав sha-файлов и основные сведения о таблицах, потому что без этого просто не удастся получить данные и увидеть их.

Известно, что компонент в sha-файле представлен названием, перед которым идёт слово Add и открывающая скобка. Вроде бы выход очевиден: искать это сочетание и считывать название компонента, но не так всё просто. Если вы работали со списком строк, то знаете, что в его параметр Strings можно задать набор строк, который будет сохранён в файле sha. Но ведь в этом тексте можно написать и слово "Add", и скобку, что полностью сымитирует компонент, но будет являться лишь текстом!

Поэтому придётся использовать другой способ. Любой компонент в sha-файле начинается с новой строки. И компонент "список строк" - тоже. И перед словом "Add" компонента ничего, кроме пробелов, быть не может. А вот перед текстом из параметра Strings всегда стоит название параметра (т.е. Strings), что уже исключает интерпретирование частей текста как компонентов или каких-то других служебных слов.


Именно поэтому перебирать надо всю строку и искать в ней Add. А если перед ним есть пробелы? Естественно, нужно их убирать.



Нажатие кнопки запускает поиск файлов на всём диске C:, но не торопитесь её нажимать, ведь если файлов sha у вас много, то поиск займёт немало времени, а пользы от него пока что никакой. Лучше посмотрите, что происходит после нахождения каждого файла - загрузка его в список строк. Однако это невизуальный список строк, он может хранить в себе строки, но не отображать их. Компонент находится на вкладке "Строки".

Второе событие разветвителя, происходящее также после каждого найденного файла, вызывает перебор массива строк в списке. А вот компонент Trim и удаляет пробелы в конце и в начале строки из потока. Это его функция - удалять заданный в параметре Char символ.

Затем, когда пробелов в начале уже точно нет, происходит копирование первых 4-х символов строки. Именно столько нужно, чтобы убедиться в наличии или отсутствии Add(. И считать имеющей компонент только ту строку, в которой эти символы есть. А после этого надо считать название компонента, которое располагается сразу после открывающей скобки и до запятой, которая отделяет имя компонента от идентификатора.



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

Для начала в компоненте Math мы устанавливаем начальное значение (а точнее - сбрасываем значение у точки свойств Result до того, которое прописано в параметре Default). Этот компонент будет каждый раз прибавлять единицу, указывая на позицию следующего символа, который нужно скопировать, и начальное значение должно быть 4 - ведь со следующей, пятой позиции начинается имя компонента.

Следующим событие мы очищаем результат в компоненте StrCat. Для чего это, вы поймёте позже.

Ну а затем выполняем математическую операцию - прибавляем к первому операнду (который у нас берётся из результата, а его мы установили в 4) единицу. По событию onResult происходит копирование одного символа из строки, получившейся после удаления пробелов. Позицию этого символа указывает нам результат математической операции, и первый раз это 5.

Элемент Case проверяет, не запятая ли этот символ. Если не запятая, то происходит сложение строк, первая из которых - это результат предыдущего сложения (вот зачем мы его очищали - чтобы при каждом новом компоненте он был пуст), а вторая - наш скопированный символ. Ну а второе событие вновь осуществляет прибавление единицы, и результат будет уже 6.

Ну а если встретилась запятая? Это значит, что название компонента кончилось, и надо теперь регистрировать его. И здесь нам нужна будет таблица.



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

Когда скопированный символ является запятой, то добавлять его к строке не надо, это уже не название компонента. Вместо этого мы запускаем цикл со счётчиком. Первое его значение задаётся параметром Start и равно 0 (помните, что в списках, таблицах и т. п. первый элемент имеет индекс 0). Конечное значение задаётся количеством строк в таблице, но оно должно быть на 1 меньше, потому что последний элемент таблицы имеет индекс (Общее количество - 1). Чтобы не использовать математику, мы поставили параметр IncludeEnd=False. Это означает, что последнее срабатывание цикла не произойдёт.

Что делает каждое срабатывание цикла? Оно читает из первого (под индексом 0!) столбца матрицы текст и сравнивает его с тем, что получился при сложении символов. Ведь именно в первом столбце мы будем хранить названия компонентов. Если текст не совпадает, то это ещё ничего не означет - название может быть в любой строке. А вот если совпало, то это точно означает, что такой компонент в таблице уже есть.

Когда мы в этом убедились, то прерываем цикл (в дальнейшем переборе уже нет смысла: мы нашли то что искали) и извлекаем из второго столбца таблицы (в той строке, в которой найдено совпадение) текст (а это количество использования компонента) и прибавляем к нему 1 (конечно, он автоматически преобразуется в число, и прибавление идёт к числу). А затем в ту же ячейку записываем значение.

А как узнать, что компонента нет в таблице? В этом нам помогает параметр цикла onBreakEnable=True. При таком его положении событие onStop происходит только при естественной остановке цикла, а если было принудительное завершение (doStop), то событие это не происходит. Ну а doStop-то мы вызываем только при нахождении совпадения. Значит, onStop сработает только тогда, когда совпадения не было.

И по этому событию мы просто добавляем новую запись в таблицу, не забывая во второй столбец занести 1, ведь один-то раз компонент уже использован, раз мы его нашли!

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



И теперь вы будете всегда осведомлены о количестве использованных компонентов. У меня, например, максимум пришёлся на Hub и MainForm. Свои результаты, если хотите, можете оставлять в комментариях.






Выпущенная по постановлению президиума ЦИК СССР Большая Советская Энциклопедия содержит множество статей на тему политики, экономики, а главное внимание уделяется Советкому Союзу, его хозяйству.

Строите дом и нужно проектирование деревянных лестниц? Баг-плюс выполнит и проектирование лестниц, и монтаж, и установку лестниц в вашем доме.

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

Отправить комментарий