Хакер писал(а):Да, кстати, сколько же стоит твоё время?
1.Счетчики теперь i и j, и они глобальны на уровне класса
Все аргументы теперь ByVal. Хакер. Первый урок на эту тему я уяснил.
Private Type KeyI
NameK As String ' стало быть имя ключа
ValueK As String ' и значение
End Type
' походу секция?
Private Type Sect
CountKey As Integer
CountS As Integer '\\Добавил поле количество секций
NameS As String ' таки имя
ValuesS() As KeyI ' массив ключей... ага
End Type
Public Sub MakeINIFile(ByVal Path As String, Optional ReMake As Boolean)
Почему столько ошибок в постинге?
Комментарии написаны отстойным образом.
Неправда. Optional ReMake As Boolean не ByVal.
А ещё Path As String у FileExists
Вывод ошибок сделан неправильно. Для вывода ошибок никогда (кроме некоторых случаев) не используют MsgBox.
Колерантны.....что такое Koler вообще? В английском такого нет. Из какого этого языка?
Причём, это может быть как смысловой тип (венгерская для приложений), так и фактический (венгерская системная). Или комбинация.
Покажи как надо, седлал как смог....
//
// Функция search_index_article($article_id,
// $article_name,
// $article_description)
// Назначение:
// Прозводит поисковую индексацию товара, добавляя в таблицу поисковой
// индексации записи для всех основ слов, встречающихся в описании и
// названии товара.
// Аргументы:
// $article_id Идентификатор товара
// $article_name Наименование товара
// $article_description Описание товара
// Примечание:
// Наименование и идентификатор функция очищает от несемантических данных сама.
// Среда работы:
// Требует загруженности shanrak.php\bbcodes, DBMS-AL, минисистемы
//
function search_index_article($article_id, $article_name, $article_description)
{
global $search_stopwords;
global $db;
if(!defined('STEMMER_PRESENT'))
{
inc('engine/search/wordbaser.php');
}
if(!isset($search_stopwords))
{
inc('engine/search/stopwords.php');
}
// Очищаем входные данные от несемантических элементов (bbcode-ов,
// символов разметки и т.п.)
$article_name = bbcode_clear($article_name, $article_id);
$article_description = bbcode_clear($article_description, $article_id);
$article_name = html_entity_decode($article_name);
$article_description = html_entity_decode($article_description);
// Сначала выделим из текста слова ( \w+ )
preg_match_all('/\b\w+\b/', $article_name, $keywords_name);
preg_match_all('/\b\w+\b/', $article_description, $keywords_descr);
$keywords_name = $keywords_name[0];
$keywords_descr = $keywords_descr[0];
// Затем сократим их до основ
$keywords_name = array_map('stemmer_process_word', $keywords_name);
$keywords_descr = array_map('stemmer_process_word', $keywords_descr);
// Затем убирём повторяющиеся основы
$keywords_name = array_unique($keywords_name);
$keywords_descr = array_unique($keywords_descr);
// Затем исключим из них стоп-слова
$keywords_name = array_values(array_diff($keywords_name, $search_stopwords));
$keywords_descr = array_values(array_diff($keywords_descr, $search_stopwords));
// Соберём INSERT-запрос для обоих типов слов:
for($i = 0; $i < count($keywords_name); $i++)
{
$parts[] = "('{$keywords_name[$i]}', '1', '$article_id')";
}
for($i = 0; $i < count($keywords_descr); $i++)
{
$parts[] = "('{$keywords_descr[$i]}', '2', '$article_id')";
}
$insertion_clause = join(",\r\n", $parts);
$sql = "INSERT INTO `t_search_index`
(`si_keyword`,
`si_context`,
`si_article_id`)
VALUES
" . $insertion_clause;
$db->query($sql);
if($db->error_info(EI_NUMBER))
{
error_die(CRITICAL_ERROR, "Не удаётся произвести поисковую индексацию товара [ID товара = '$article_id']. Сбой при работе с БД.".dberrordef());
}
}
Select Case lSize
Case 0 To POOL_MIN_SIZE
' Нам нужен пустой кипер.
InfoProvider.AddFromString POOL_KEEPER_PREFIX + _
POOL_KEEPER_POSTFIX
AllocateCodePool = POOL_MIN_SIZE
Exit Function
Case POOL_MIN_SIZE To POOL_1Q_SIZE
' Нам нужен кипер с одним квантом
InfoProvider.AddFromString POOL_KEEPER_PREFIX + _
POOL_KEEPER_QUANT + _
POOL_KEEPER_POSTFIX
AllocateCodePool = POOL_1Q_SIZE
Exit Function
Case POOL_1Q_SIZE To POOL_2Q_SIZE
' Нам нужен кипер с двумя квантами
InfoProvider.AddFromString POOL_KEEPER_PREFIX + _
POOL_KEEPER_QUANT + _
POOL_KEEPER_QUANT + _
POOL_KEEPER_POSTFIX
AllocateCodePool = POOL_2Q_SIZE
Exit Function
Case Is > POOL_2Q_SIZE
' Нужен кипер с множеством квантов
Dim lQuants As Long
Dim sBuffer As String
lQuants = Ceil(lSize - POOL_CONST_SIZE, POOL_GROW_QUANT) \ POOL_GROW_QUANT
AllocateCodePool = POOL_CONST_SIZE + POOL_GROW_QUANT * lQuants
Dim str As String ' Ну это наверноме может быть таки буфер???
Знаю. А в чем разница то? В том что в моем случае это по определению не ошибка, а окно сообщения с критическим выходом.
А в остальном. Все это только про прально непрально написано, не так красиво и т.д. Для меня на данном этапе очень важен функционал, а он сейчас страдает в как минимум двух процедурах. Вот здесь мне реально нужна помощь. Может я чего-то не знаю...
А вот если на раннем этапе научишься дурацким практикам комментирования и наименования, отучиться потом будет почти нереально.
интересного сложного проекта, который нафиг никому оказался не нужен.
Где ты увидел кучу отзывов?
(пишу продолжение оценки)
Ну восхищений-то точно было куча
Но, дело не в этом. Дело в том, что никто не юзает. Я потратил очень много времени чтобы сделать общедоступный инструмент. Сделать DLL-ку с экспортами я мог бы себе сам с помощью отладчика и Hex-редактора, и это зянало бы минут 10. А здесь ... и в пустую.
Err.Raise 10, , "Откуда такая сеция?" 'нут тут понятно, проверяем правильность индекса
Open Path For Input As FNumber ' Считываем по строкам в массив
Do While Not EOF(FNumber) 'До конца файла
Line Input #FNumber, ReedStrg 'Читаем очередную строку в пер-ю ReedStrg
i = i + 1 'прибавляем к счетчику 1
ReDim Preserve ArrayString(i) 'Переопределяем массив на значение счетчика
ArrayString(i) = ReedStrg 'Записываем в последний эл-т строку
Loop 'Следующая строка
Close FNumber 'Закарываем файл
If i > 0 Then 'Если строки есть то
For i = LBound(ArrayString) To UBound(ArrayString) 'С верха до низу массива строк
'Если левый символ строки без пробелов по бокам равен [ то...
If Left$(LTrim$(RTrim$(ArrayString(i))), 1) = LeftD Then
IndexSec = IndexSec + 1 'прибавляем счетчик секций
ReDim Preserve SectionArr(IndexSec) 'Переопределяем массив секций на значение счетчика секций
'заодно записываем имя секции без пробелов с двух сторон
SectionArr(IndexSec).NameS = LTrim$(RTrim$(ArrayString(i)))
'В поле CountS записываем кол-во секций
SectionArr(1).CountS = IndexSec
'Ключей в этой секции 0
SectionArr(IndexSec).CountKey = 0
Index = 0 'обнуляем счетчик ключей, т.к. след-й видимо будет ключ
Else 'Иначе если слева не [, то...
If Left$(LTrim$(RTrim$(ArrayString(i))), 1) <> Comment Then 'Если это не комментарий, то
If InStr(1, ArrayString(i), Koler) > 0 Then 'Если в строке есть знак =, то..
Index = Index + 1 'Мы нашли ключ, прибаляем счетчик ключей на 1
'Записываем в поле CountKey значение кол-ва ключей секции IndexSec
SectionArr(IndexSec).CountKey = Index
'Переопределяем маасив ключей в секции IndexSec на значение счетчика Index
ReDim Preserve SectionArr(IndexSec).ValuesS(Index)
'Записываем туда имя ключа и его значение без пробелов и знака =
SectionArr(IndexSec).ValuesS(Index).NameK = LTrim$(RTrim$(Mid$(LTrim$(RTrim$(ArrayString(i))), 1, InStr(1, (LTrim$(RTrim$(ArrayString(i)))), "=") - 1)))
SectionArr(IndexSec).ValuesS(Index).ValueK = LTrim(RTrim$(Mid$(LTrim$(RTrim$(ArrayString(i))), InStr(1, LTrim$(RTrim$(ArrayString(i))), "=") + 1)))
[Section] ; Комментарий
foo=123 ; Тоже комментарий
; Такой "код" твой модуль не переварит...
Public Sub AddKeyInSection(ByVal Section As String, ByVal Key As String, ByVal ValKey As String)End Sub
Dim myIni As C
' ...
myIni.MakeINIFile(...)
myIni.AddKeyInSection "MySect", "Вес", "900кг"
myIni.Sections("MySect").AddKey "Вес", "900кг"
Dim MySect As CSection
Set MySect = myIni.Sections("MySect")
MySect.AddKey "Weight", "900kg"
MySect.AddKey "Voltage", "380V"
MySect.AddKey "Protection", "IP20"
Set MySect = Nothing
Хакер писал(а):Дело в том, что никто не юзает. Я потратил очень много времени чтобы сделать общедоступный инструмент. Сделать DLL-ку с экспортами я мог бы себе сам с помощью отладчика и Hex-редактора, и это зянало бы минут 10. А здесь ... и в пустую.
описание исправлю, а какой номер допустим?Во-первых, номер 10 использовать нелья - это номер стандартнй ошибки 10 :: This array fixed or temporary locked. Во-вторых, в качестве описание ошибки строку "Откуда такая секция?" использовать недопустимо.
Я бы сделал иначе. Сделал бы гранулярность изменения побольше. Т.е бы делал в массиве изначально 256 элементов. И читал строки в низ. Если бы при выделении этих 256 не хватало бы - выделял бы ещё 256 и продолжал бы читать.
По достижении EOF, удалял бы лишнюю часть.
Так что я бы, как я тебе уже говорил, прочитал весь файл разом в буфер, а потом бы его обрабатывал.
Чем меньше операций со строками - тем лучше для производительности (тебе ведь её, кажется, не хватало?)
Ага....и удаляем все пробелы вообще. А если в имени ключа два слова?И второе: Вместо LTrim(RTrim(..)) надо использовать Trim(...).
Третье: ты так и не избавился от дурацкого парсинга, основанного на Mid$, InStr, Trim$ и прочей гадости (в рамках парсинга).
Такой "код" твой модуль не переварит...
(при таком подходе секция MySect ищется один раз. У тебя же если три раза добавлять ключи с помощью AddKeyInSection, нужная секция будет искаться каждый раз, что очень неэффективно).
Посмотри, сколько мест для оптимизации нашлось
(прожолжение следует)
описание исправлю, а какой номер допустим?
Я тогда не понял, и сейчас не понимаю. В буфер - это куда.
Ага....и удаляем все пробелы вообще. А если в имени ключа два слова?
Trim(" Hello ") будет "Hello".
LTrim(" Hello ") будет "Hello "
RTrim(" Hello ") будет " Hello"
LTrim(RTrim(" Hello ")) будет LTrim(" Hello") будет "Hello".
??? Каким еще образом можно определить что в строке символ "=" или что левый символ равен "[" и т.д. Если есть, то я видимо пол жизни потерял...
И в чём разница? И что ты хотел сказать своим "Ага"?
Да хоть куда. Хоть в строковую переменную, хоть в байтовый массив, хоть в блок памяти выделенный с помощью HeapAlloc/VirtualAlloc/LocalAlloc/GlobalAlloc.
Буфер, это хитрая фишка VB! Laughing
Инициализируется примерно так:
А ты посмотри на ДКА-лексер (или ДКА-парсер, -- не помню как он пиисал в комментариях, но я думаю, найдёшь) в Тёмычевском эвалюаторе.
А я куда считываю. В массив строковых переменных. Это не буфер?
[ Ascschebka ] [sdOipo ] [ s] [kiam] [ olkun]
Ascschebka
sdOipo
s
kiam
Debug.Print "Ы!" если не знаешь, что это
Private Sub SectionFind(ByVal StringFind As String)
Dim OneSymbol As String
Dim OneSymbolInSection As String
Const LEFT_BRACKET = "["
Const RIGHT_BRACKET = "]"
Dim Section As String
Dim i As Long
Dim j As Long
For i = 1 To Len(StringFind) 'С начала до конца строки
OneSymbol = Mid$(StringFind, i, 1) 'Один символ, вырезанный со строки с позиции i
If OneSymbol = LEFT_BRACKET Then 'Если он равен [ то....
Section = vbNullString 'Обнуляем название секции
j = i + 1 'Находим позицию где начинается [, со следующей начинается имя секции
OneSymbolInSection = vbNullString 'Символ для прочтения имени секции обнуляем
Do While OneSymbolInSection <> RIGHT_BRACKET 'Делаем уикл, пока не найдем ]
OneSymbolInSection = Mid$(StringFind, j, 1) 'Выризаем один исмвол из строки позиции j
Section = Section + OneSymbolInSection 'В переменную Section прибавляем каждый символ
j = j + 1 'Приращиваем j для выризания след-го символа
Loop 'Убираем все пробелы и правую ]
Section = Trim$(Mid$(Section, 1, Len(Section) - 1))
Debug.Print Section 'печатаем что получилось
i = j - 1 'Чтобы опять не пробегать то что уже пробежали(При считывании имени секции)
'делаем так чтобы сдледуюий шаг начинался с того места где нашли последний ]
End If
Next i
End Sub
OneSymbolInSection = vbNullString 'Символ для прочтения имени секции обнуляем
1) И зачем обнулять?
2) И почему бы не использовать уже имеющуюся OneSymbol?
If Mid$(Buffer, i, 1) = LEFT_BRACKET Then
j = i '+ 1
Do
j = j + 1
OneSymbol = Mid$(Buffer, j, 1)
Loop Until OneSymbol = RIGHT_BRACKET
Section = Mid$(Buffer, i + 1, j - i - 1)
Section = Trim$(Section)
'Debug.Print Section
i = j '- 1
End If
Сейчас этот форум просматривают: Yandex-бот и гости: 4