Date de publication : 01/09/2006
Par
Igor2004 (nikiforov.developpez.com/foxpro/russe)
Пользовательские функции FoxPro Дамы и Господа, Я хотел бы предложить вам бесплатно следующие пользовательские функции FoxPro, написанные на C, вместе с исходными текстами. IFOR() "непосредственный" FOR цикл IWHILE() "непосредственный" WHILE цикл ICASE() "непосредственный" CASE условный переход IEXECCASE() "непосредственный" CASE условный переход, с выполнением одной или нескольких команд после условий IEXECIF() "непосредственный" IF условный переход, с выполнением одной или нескольких команд после условий EXECUTE() выполняет строку команд, разделенных символом “;”, подобно макроподстановке NPRECISION() возвращает количество знаков после десятичной точки в числовом выражении FIELDNUM() возвращает порядковый номер поля в таблице по имени поля DANSLISTE() определяет находится ли число в списке значений типа "1,5,13-18" INCREMENT() увеличивает переменную на 1 и возвращает результат STRFILTER() удаляет все символы из первой строки, за исключением символов, содержащихся во второй строке REVERSE() возвращает строку в обратном порядке Функции для работы с массивами ARRAYSUM() возвращает сумму числовых элементов заданного столбца массива ARRAYAVG() возвращает среднее значение числовых элементов заданного столбца массива ARRAYMIN() возвращает минимальное значение элементов заданного столбца массива ARRAYMAX() возвращает максимальное значение элементов заданного столбца массива ARRAYCNT() возвращает количество числовых элементов заданного столбца массива ASCANQUICK() аналогична встроенной функции ASCAN(), за исключением того, что осуществляет бинарный поиск по столбцу в заранее отсортированном массиве VITESCAN() осуществляет бинарный поиск по столбцу в отсортированном массиве GETALLWORDS() помещает в глобальный массив все слова из строки или memo поля Функции конвертации арабских чисел в римские и наоборот ARABTOROMAN() преобразует обычное число в римское число (от 1 до 3999) ROMANTOARAB() преобразует римское число в обычное число (от I до MMMCMXCIX) Более 18 000 человек во всем мире уже загрузили мои функции, надеюсь, что и данные функции будут полезными и для Вас. Вышеупомянутые функции имеются для следующих версий FoxPro (VFP 9.0, 8.0, 7.0 и т.д., FoxPro 2.6 for DOS). Файл библиотеки с версией для Visual FoxPro имеет расширение имени файла fll, для FoxPro 2.6 for DOS расширение имени файла plb. Поместите библиотеку в один из тех каталогов, в котором FoxPro осуществляет поиск файлов, либо в команде укажите полный путь к библиотеке. Для использования данных функций выполните следующую команду : set library to St_Denis additive либо set library to <путь к библиотеке>St_Denis additive Для удаления данных функции из памяти выполните следующую команду : release library St_Denis либо release library <путь к библиотеке>St_Denis В файл архива входят : 1) St_Denis.fll библиотека для VFP 8.0 и ниже 2) St_Denis.fll библиотека для VFP 9.0 3) St_Denis.plb библиотека для FoxPro 2.6 for DOS 4) St_Denis.c исходный текст библиотеки 5) St_Denis_Russian.chm подробное описание функций библиотеки, с примерами их использования, дополнительные материалы, среди которых пошаговое описание того, как компилировать библиотеку в Visual Studio .NET 2005 (2003). 6) St_Denis.prg реализация некоторых функций библиотеки на FoxPro. 7) test_perf.prg тесты, позволяющие наглядно получить преставление о быстродействии некоторых функций библиотеки, сравнение быстродействия функций библиотеки со встроенными функциями и командами FoxPro. 8) mkeywords.prg построение таблицы ключевых слов из memo поля. С наилучшими пожеланиями, Игорь Никифоров |
Вот детальное описание нескольких функций, каждая функция из библиотеки имеет подробное, может быть даже излишне подробное, описание. GETALLWORDS() Помещает в глобальный массив все слова из строки или memo поля, возвращает максимальную длину слова из строки, если в строке нет слов, возвращает 0. GETALLWORDS(ArrayName, lcString[, lcDelimiters]) Тип возвращаемого значения числовой Описание структуры создаваемого массива первый столбец, числовой тип – порядковый номер слова в строке lcString второй столбец, символьный тип - слово третий столбец, числовой тип – позиция в строке lcString, с которой начинается слово четвертый столбец, числовой тип - длина слова Параметры ArrayName символьный тип – имя создаваемого функцией глобального массива lcString символьный тип – строка, слова которой будут помещены в массив, строка может передаваться как по значению, так и по ссылке, по ссылке необходимо передавать к примеру memo поля. lcDelimiters символьный тип, наибольшая длина 256 символов - необязательный параметр, определяет те символы, которые будут служить разделителями слов в строке lcString. Разделителями по умолчанию являются пробелы, символы табуляции, возврата каретки и перевода строки. GETALLWORDS() считает каждый символ из строки lcDelimiters как отдельный разделитель, а не всю строку lcDelimiters как единый разделитель. Примечания: GETALLWORDS() по умолчанию считает, что слова разделены пробелами, символами табуляции, возврата каретки и перевода строки. Если передан параметр lcDelimiters, функция игнорирует пробелы, символы табуляции, возврата каретки и перевода строки. Если массив или переменная с именем ArrayName уже существовал, массив или переменная будут удалены и будет создан новый массив. Если массив или переменная ArrayName уже существовало со статусом Public, а затем были объявлены в команде Private, то функция выдаст ошибку, это связано с тем, что она в такой ситуации может освободить только частную (но не глобальную) переменную или массив, но при попытке создать внутри функции массив заново выдается ошибка, поскольку массив или переменная уже существуют. Лучше всего использовать функцию SYS(2015) для получения уникального имени массива, и затем либо помещать его в таблицу либо копировать в локальный массив, после чего удалять. Функция в версиях до 8.0 включительно, может поместить в массив 16250 слов максимум (версия для DOS 2800 слов), поскольку максимальный размер массива 65000 элементов, массив имеет 4 столбца, а в LCK версии 9.0 может поместить в массив 65000 слов максимум. При невыполнении данного условия, то есть когда количество слов превышает максимально допустимое появится сообщение об ошибке "Too many variables". Одноименная функция написанная на VFP 9.0 может поместить значительно больше слов, но так чтобы массив не занимал более 2 Гигабайт памяти. Функция GETALLWORDS(), так же как и встроенные функции VFP GETWORDNUM(), GETWORDCOUNT(), не работает со строкам содержащими символ с кодом нуль. Если строка содержит символ с кодом нуль, то вышеупомянутые функции возвращают неправильный результат, это связано с тем что в языке C++ нулевой символ интерпретируется строковыми функциями как конец строки. Примеры: Set Library To St_Denis Additive Clear ?'1 example ' Local lcString, lcMaxLenWord, lcUniqArrayName lcString = '- Французский язык знаете, надеюсь?'+Chr(10)+Chr(13)+; '- Очень плохо. В пределах гимназического курса.'+Chr(10)+Chr(13)+; '- Гм... Придется орудовать в этих пределах. Сможете ли вы'+Chr(10)+Chr(13)+; 'сказать по-французски следующую фразу: "Господа, я не ел шесть дней"?'+Chr(10)+Chr(13)+; '- Мосье,- начал Ипполит Матвеевич, запинаясь,-мосье, гм,'+Chr(10)+Chr(13)+; 'гм... же не, что ли, же не манж па... шесть, как оно: ен, де,'+Chr(10)+Chr(13)+; 'труа, катр, сенк... сис... сис... жур. Значит, же не манж па сис жур.'+Chr(10)+Chr(13)+; '- Ну и произношение у вас, Киса! Впрочем, что от нищего требовать!'+Chr(10)+Chr(13)+; 'Конечно, нищий в Европейской России говорит по-французски хуже, чем Мильеран.'+Chr(10)+Chr(13)+; 'Ну, Кисуля, а в каких пределах вы знаете немецкий язык?'+Chr(10)+Chr(13)+; '- Зачем мне это все?-воскликнул Ипполит Матвеевич.'+Chr(10)+Chr(13)+; '- Затем, сказал Остап веско, что вы сейчас пойдете к "Цветнику",'+Chr(10)+Chr(13)+; 'станете в тени и будете на французском, немецком и русском языках просить подаяние,'+Chr(10)+Chr(13)+; 'упирая на то, что вы бывший член Государственной думы от кадетской фракции.'+Chr(10)+Chr(13)+; 'Весь чистый сбор поступит монтеру Мечникову.' lcUniqArrayName = Sys(2015) lcMaxLenWord = GETALLWORDS(lcUniqArrayName, lcString) If lcMaxLenWord > 0 Create Table ALLWORDS Free (WORDNUM N(4), Word C(lcMaxLenWord), STARTWORD N(4), LENGTHWORD N(4)) Append From Array (lcUniqArrayName) Release (lcUniqArrayName) Browse Endif lcUniqArrayName = Sys(2015) lcMaxLenWord = GETALLWORDS(lcUniqArrayName, lcString,' ,.') List Memory Like (lcUniqArrayName) Release (lcUniqArrayName) ?' lcMaxLenWord ', lcMaxLenWord ** во втором примере memo поле notes таблицы Employee передается по ссылке, ** поэтому перед именем стоит значок @ ?'2 example work with memo field' Close Database Open Database (Home(2) + 'data\testdata') Noupdate Use employee Noupdate In 0 Select Employee Go 1 lcUniqArrayName = Sys(2015) lcMaxLenWord = GETALLWORDS(lcUniqArrayName, @Employee.notes) If lcMaxLenWord > 0 Create Table KEYWORDS Free (WORDNUM N(4), Word C(lcMaxLenWord), STARTWORD N(4), LENGTHWORD N(4)) Append From Array (lcUniqArrayName) Release (lcUniqArrayName) Browse Endif Release Library St_Denis ------------------------------------------------------- ARRAYMAX (@ArrayName, [nSearchColumn [, nStartRow [, nRowsSearched [, @NumRowWithMaxElem]]]] ) Возвращает максимальное значение элементов заданного столбца массива. Возвращает значение числового, денежного, символьного типа, типа дата, время, типа дата Первый параметр ArrayName – массив, передаваемый по ссылке, поэтому перед именем массива всегда должно стоять @. Второй (необязательный) параметр nSearchColumn числовой тип, номер столбца, в котором функция будет искать максимальное значение, по умолчанию поиск осуществляется в первом столбце. Третий (необязательный) параметр nStartRow числовой тип, номер строки, начиная с которой будет осуществляться поиск, по умолчанию поиск осуществляется с первой строки. Четвертый (необязательный) параметр nRowsSearched числовой тип, количество строк, начиная с nStartRow, в которых будет осуществляться поиск, по умолчанию поиск осуществляется до последней, включительно, строки. Пятый (необязательный) параметр NumRowWithMaxElem, передаваемый по ссылке переменная, которой будет присвоен номер строки массива, содержащего максимальное значение. Передайте –1 для необязательных параметров, если, скажем, нужно всего лишь передать параметр NumRowWithMaxElem, не указывая явно, предыдущие необязательные параметры. Данная функция ищет максимальное значение для числовых (денежных), символьных, дата (дата, время) элементов. Приоритет нахождения максимального значения в том случае, если контекст поиска содержит элементы разных типов следующий: сначала предполагается, что ищется максимальное значение для числовых (денежных) элементов, при этом денежные элементы (если встретятся) преобразуются в числовые, в случае, если в контексте поиска не встретилось ни одного числового (денежного) элемента, предполагается, что ищется максимальное значение для символьных элементов, если в контексте поиска не встретилось ни одного символьного элемента, предполагается, что ищется максимальное значение для элементов типа дата, время при этом элементы типа дата (если встретятся) преобразуются в элементы типа дата, время. В случае, когда ни одного из элементов вышеупомянутого типа не встретится, возвращается логическая ложь .F. При сравнении символьных элементов учитывается текущая установка set(‘exact'), скажем при Set Exact Off ?'asdf' < 'asdf ' && возвращает .T. ?'asdf'='asdf ' && возвращает .F. Set Exact On ?'asdf' < 'asdf ' && возвращает .F. ?'asdf'='asdf ' && возвращает .T. Примеры: Set Library To St_Denis Additive Clear Close Database Open Database (Home(2) + 'data\testdata') Noupdate Use customer Noupdate Select Country, Maxordamt From customer Into Array ArrMaxordamt Order By 1 nMaxElemRow = 0 =ARRAYMAX(@ArrMaxordamt , 2, -1, -1, @nMaxElemRow) ?nMaxElemRow,' строка массива ArrMaxordamt с максимальным значением второго столбца ', ArrMaxordamt(nMaxElemRow,1), ArrMaxordamt(nMaxElemRow,2) ?Replicate('-',50) Use products Noupdate Select * From products Into Array ArrProducts nMaxElemRow = 0 lcSaveExact = Set('exact') Set Exact Off =ARRAYMAX(@ArrProducts, 2, -1, -1, @nMaxElemRow) ?nMaxElemRow,' строка массива ArrProducts с максимальным значением второго столбца (set exact off) ', ArrProducts(nMaxElemRow,2) Set Exact On =ARRAYMAX(@ArrProducts, 2, -1, -1, @nMaxElemRow) ?nMaxElemRow,' строка массива ArrProducts с максимальным значением второго столбца (set exact on) ', ArrProducts(nMaxElemRow,2) ?Replicate('-',50) * убираем пробелы For lnI = 1 To Alen(ArrProducts, 1) ArrProducts(lnI, 2) = Alltrim(ArrProducts(lnI, 2)) Endfor ?' добавим пробел к одному из элементов, чтобы показать разницу результатов в зависимости от установки Set Exact ' ArrProducts(nMaxElemRow + 1, 2) = ArrProducts(nMaxElemRow, 2) + Space(1) Set Exact Off =ARRAYMAX(@ArrProducts, 2, -1, -1, @nMaxElemRow) ?nMaxElemRow,' строка массива ArrProductsс с максимальным значением второго столбца (set exact off) ', ArrProducts(nMaxElemRow,2) Set Exact On =ARRAYMAX(@ArrProducts, 2, -1, -1, @nMaxElemRow) ?nMaxElemRow,' строка массива ArrProductsс максимальным значением второго столбца (set exact on) ', ArrProducts(nMaxElemRow,2) Set Exact &lcSaveExact ?Replicate('-',50) ** искусственно создаем столбец, содержащий значения разных типов ** поскольку есть значения числового типа, максимум ищется только среди числовых значений For lnI = 1 To Alen(ArrProducts, 1) If Mod(lnI,3) = 0 ArrProducts(lnI, 2) = Val(ArrProducts(lnI, 1)) && Numeric Endif If Mod(lnI,5) = 0 ArrProducts(lnI, 2) = Ntom(Val(ArrProducts(lnI, 1))) && Currency Endif If Mod(lnI,7) = 0 ArrProducts(lnI, 2) = Date() - lnI && Date Endif If Mod(lnI,17) = 0 ArrProducts(lnI, 2) = .F. && Logical Endif Endfor =ARRAYMAX(@ArrProducts, 2, -1, -1, @nMaxElemRow) ?nMaxElemRow,' строка массива ArrProducts с максимальным значением второго столбца ', ArrProducts(nMaxElemRow,2) ** создаем столбец, содержащий значения типа дата For lnI = 1 To Alen(ArrProducts, 1) ArrProducts(lnI, 2) = Date() - lnI * Iif(Mod(lnI,2) = 0, -1, 1) If Mod(lnI,17) = 0 ArrProducts(lnI, 2) = .F. && Logical Endif Endfor =ARRAYMAX(@ArrProducts, 2, -1, -1, @nMaxElemRow) ?nMaxElemRow,' строка массива ArrProducts с максимальным значением второго столбца типа дата', ArrProducts(nMaxElemRow,2) Release Library St_Denis ------------------------------------------------------- IFOR () ЋнепосредственныйЛ FOR цикл Выполняет одну или несколько команд в FOR цикле, возможное полезное применение, например, в отчетах. IFOR (cExpression, nFinalValue, cExecutedExpressions [,nIncrement[, ReturnedExpression]]) Тип возвращаемого значения определяется пользователем, по умолчанию Logical .F. Параметры Первый параметр cExpression символьный тип в данной строке осуществляется объявление и присвоение начального значения переменной for цикла, например, ”i = 1”, данная строка будет выполнена аналогично выполнению макроподстановки Второй параметр nFinalValue числовой тип конечное значение переменной for цикла Третий параметр cExecutedExpressions символьный тип строка исполняемых внутри цикла команд, разделенных символом “;”, причем циклы и условные переходы не поддерживаются, каждая подстрока из строки будет выполняться подобно макроподстановке. Четвертый (необязательный) параметр nIncrement числовой тип шаг for цикла, по умолчанию 1 Пятый (необязательный) параметр ReturnedExpression символьный тип переменная или выражение, которое будет оценено подобно тому, как оценивает выражения функция EVALUATE() и результат оценки затем будет возвращен функцией IFOR, по умолчанию возвращается .f. Примеры: 1) выводит на устройство вывода квадраты первых 25 натуральных чисел и возвращает сумму ряда квадратов первых 25 натуральных чисел, создавая при этом массив, содержащий квадраты первых 25 натуральных чисел. Set Library To St_Denis Additive Clear Sum_Elems = 0 ?IFOR("i=1",25,"dimension laArr(i) ;laArr(i) = i**2;?laArr(i);Sum_Elems=Sum_Elems+laArr(i)",1,"Sum_Elems") * это полностью аналогично следующему коду Sum_Elems = 0 For i = 1 To 25 Dimension laArr(i) laArr(i) = i**2 ?laArr(i) Sum_Elems = Sum_Elems + laArr(i) Endfor ?Sum_Elems Release Library St_Denis 2) выводит на устройство вывода первые 25 чисел Фибоначчи и возвращает сумму ряда из первых 25 чисел Фибоначчи Set Library To St_Denis Additive Clear Sum_Fibonacci_numbers = 0 ?IFOR("i=1",25,"fn_2 = iif(i>1,fn_1,0);fn_1=iif(i>1,fn,1);fn=fn_1+fn_2;?fn;Sum_Fibonacci_numbers=Sum_Fibonacci_numbers+fn",1,"Sum_Fibonacci_numbers") * это полностью аналогично следующему коду Sum_Fibonacci_numbers = 0 For i = 1 To 25 fn_2 = Iif(i>1,fn_1,0) fn_1 = Iif(i>1,fn,1) fn=fn_1+fn_2 ?fn Sum_Fibonacci_numbers=Sum_Fibonacci_numbers+fn Endfor ?Sum_Fibonacci_numbers Release Library St_Denis |