Класс CustomКласс Custom — это один из «лёгких» базовых
классов Visual FoxPro, позволяющий создавать не визуальные
пользовательские классы. Он имеет ограниченный по сравнению с
визуальными классами набор свойств и методов, с которыми вы можете
познакомиться в справочной документации. На его основе вы можете
создавать классы, решающие различные задачи, не требующие визуализации.
DEFINE CLASS ConvertAmount as Custom PROTECTED aHundreds[9], aTens[9], aUnits[19] * Массив наименований сотен aHundreds[1] = 'сто' aHundreds[2] = 'двести' aHundreds[3] = 'триста' aHundreds[4] = 'четыреста' aHundreds[5] = 'пятьсот' aHundreds[6] = 'шестьсот' aHundreds[7] = 'семьсот' aHundreds[8] = 'восемьсот' aHundreds[9] = 'девятьсот' * Массив наименований десятков aTens[2] = 'двадцать' aTens[3] = 'тридцать' aTens[4] = 'сорок' aTens[5] = 'пятьдесят' aTens[6] = 'шестьдесят' aTens[7] = 'семьдесят' aTens[8] = 'восемьдесят' aTens[9] = 'девяносто' * Массив наименований единиц aUnits[3] = 'три' aUnits[4] = 'четыре' aUnits[5] = 'пять' aUnits[6] = 'шесть' aUnits[7] = 'семь' aUnits[8] = 'восемь' aUnits[9] = 'девять' aUnits[10] = 'десять' aUnits[11] = 'одиннадцать' aUnits[12] = 'двенадцать' aUnits[13] = 'тринадцать' aUnits[14] = 'четырнадцать' aUnits[15] = 'пятнадцать' aUnits[16] = 'шестнадцать' aUnits[17] = 'семнадцать' aUnits[18] = 'восемнадцать' aUnits[19] = 'девятнадцать' FUNCTION Convert(tnValue) LOCAL lcSumma, lcResult, lnDec IF tnValue > 2147483647 .or. tnValue <= 0 RETURN "Число вне допустимых пределов" ENDIF lcSumma = STR(INT(tnValue),12) lcResult = this.NumToString(SUBSTR(lcSumma,1,3),"миллиард",3) lcResult = lcResult+this.NumToString(SUBSTR(lcSumma,4,3),"миллион",3) lcResult = lcResult+this.NumToString(SUBSTR(lcSumma,7,3),"тысяч",2) lcResult = lcResult+this.NumToString(SUBSTR(lcSumma,10,3),"рубл",1) lnDec = 100 * (tnValue - INT(tnValue)) RETURN UPPER(LEFT(lcResult,1)) + SUBSTR(lcResult,2) + TRANSFORM(lnDec, "@L 99") + " коп" ENDFUNC PROTECTED FUNCTION NumToString(tcValue, tcName, tnFlag) LOCAL lcResult, lnHundreds, lnTens, lnUnits, lcName, lcExt IF tcValue = " " IF tnFlag = 1 RETURN "Ноль рублей " ENDIF RETURN "" ENDIF IF tnFlag = 2 this.aUnits[1] = "одна" this.aUnits[2] = "две" ELSE this.aUnits[1] = "один" this.aUnits[2] = "два" ENDIF lcResult = "" lnHundreds = VAL(LEFT(tcValue,1)) && Выделяем количество сотен lnTens = VAL(SUBSTR(tcValue,2,1)) && ... десятки lnUnits = VAL(SUBSTR(tcValue,3,1)) && ... единицы (от 1 до 19) IF lnHundreds > 0 lcResult = lcResult + this.aHundreds[lnHundreds] + " " ENDIF IF lnTens > 1 lcResult = lcResult + this.aTens[lnTens] + " " + this.aUnits[lnUnits] + " " ELSE lcResult = lcResult + this.aUnits[10 * lnTens + lnUnits] + " " ENDIF lcResult = lcResult + tcName * * Формирование окончаний * lcExt = "" DO CASE CASE tnFlag = 1 && Рубли (единицы) lcExt = "ей" && По умолчанию "рублей" IF lnTens != 1 DO CASE CASE lnUnits = 1 && 1; 21; 31 ... lcExt = "ь" && "рубль" CASE lnUnits > 1 .and. lnUnits < 5 lcExt = "я" ENDCASE ENDIF CASE tnFlag = 2 && Тысячи IF lnTens != 1 DO CASE CASE lnUnits = 1 lcExt = "а" CASE lnUnits > 1 .and. lnUnits < 5 lcExt = "и" ENDCASE ENDIF CASE tnFlag = 3 && Миллионы, миллиарды lcExt = "ов" && По умолчанию "миллионов" IF lnTens != 1 DO CASE CASE lnUnits = 1 lcExt = "" CASE lnUnits > 1 .and. lnUnits < 5 lcExt = "а" ENDCASE ENDIF ENDCASE RETURN lcResult + lcExt + " " ENDFUNC ENDDEFINE В классе объявляются защищённые массивы, содержащие
наименования чисел, и два метода — открытый метод Convert,
которому передаётся преобразуемое число, и защищённый NumToString.
Как выполняется преобразование числа в строку, понятно из кода метода. oCnv = CREATEOBJECT("ConvertAmount") cString = oCnv.Convert(1286.55) Класс CollectionЧто такое коллекции? Коллекция — это инструмент для объединения связанных объектов в группы. Например, объект Form поддерживает коллекцию объектов — управляющих элементов Controls и имеет соответствующие методы для добавления новых элементов в коллекцию или удаления их из неё. Вы можете обратиться к любому элементу в коллекции Controls по его индексу, например: thisform.Controls[nIndex].Name Свойство ControlCount формы содержит значение,
равное количеству объектов в коллекции. При удалении объекта из
коллекции, независимо от его положения внутри коллекции, значение
свойства ControlCount уменьшается на единицу, а индексы всех
объектов, следующих в коллекции за удаляемым объектом, так же
уменьшаются на единицу. СозданиеДля создания объекта — экземпляра класса Collection можно использовать функции CREATEOBJECT() или NEWOBJECT(), например: oCollection = CREATEOBJECT('Collection') Вы можете добавлять объекты Collection в свои
классы, используя команду ADD OBJECT, либо динамически во время
выполнения в уже существующие объекты-контейнеры при помощи методов
AddObject или NewObject. СвойстваСвойство Count содержит количество элементов коллекции. Оно доступно только для чтения: nCount = oCollection.Count Свойство KeySort определяет, в какой последовательности Visual FoxPro перечисляет элементы коллекции в цикле FOR EACH. Таблица 11.13. Значения свойства KeySort класса Collection
В листинге 11.13 показано применение свойства KeySort.
oCollection.KeySort = 1 FOR EACH oItem IN oCollection ? IIF(VARTYPE(oItem) = 'O', oItem.Name, oItem) ENDFOR Остальные свойства класса Collection — общие для всех базовых классов Visual FoxPro; при необходимости вы найдёте их описание в справочной документации. МетодыИз всех методов класса мы рассмотрим здесь методы Add, Item, GetKey и Remove. Описание остальных методов класса вы можете найти в справочной документации. Метод AddМетод добавляет в коллекцию новый элемент. Вот его синтаксис: Collection.Add( eItem [, cKey [, [eBefore |, eAfter ]]] ) Параметр eItem представляет собой выражение любого типа, которое
добавляет элемент в коллекцию. oCollection.Add('Орхидея', 'Цветок1', , 'Цветок3') В листинге 11.14 показано применение метода Add.
LOCAL oItems AS Collection oItems = NEWOBJECT("Collection") oItems.Add("Орхидея", "Цветок2") oItems.Add("Роза", "Цветок1", "Цветок2") oItems.Add("Колокольчик", "Цветок3") ? oItems.Item[1],' ',oItems.GetKey(1) ? oItems.Item[2],' ',oItems.GetKey(2) ? oItems.Item[3],' ',oItems.GetKey(3) В результате выполнения этого кода вы получите следующий список:
Почему вывод произведён именно в указанной последовательности? Действительно, после добавления в коллекцию строки "Орхидея" индекс этого элемента получил значение, равное единице. Но при добавлении следующего элемента было указано, что он должен быть размещён перед элементом с ключом "Цветок2". Таким образом, элемент "Роза" получил значение индекса, равное единице, а индекс элемента "Орхидея" стал равен двум. При добавлении следующего элемента (строки "Колокольчик") его положение явно не указано, поэтому этот элемент был добавлен в конец коллекции.
Метод ItemМетод позволяет обратиться к элементу коллекции по его индексу. Вот его синтаксис: oCollection.Item(eIndex) где eIndex может быть либо числовым значением индекса элемента, либо наименованием ключа. Пример применения метода показан в листинге 11.15. Листинг 11.15. Применение метода Item объекта Collection
LOCAL oItems AS Collection, oForm AS Form oForm = NEWOBJECT("Form") oForm.Name = "MyForm" oCollection = NEWOBJECT("Collection") oCollection.Add(oForm, "Это форма") ? oCollection.Item(1).Name && Обращение по индексу ? oCollection.Item("Это форма").Name && Обращение по ключу ? oCollection(1).Name && Использование метода Item по умолчанию ? oCollection("Это форма").Name && то же Последние четыре строки кода демонстрируют варианты обращения к элементу коллекции. Все они возвращают одинаковый результат. Метод GetKeyМетод позволяет получить значение ключа по индексу элемента коллекции либо значение индекса по ключу. Если элемента с указанным индексом (или ключом) нет в коллекции, метод возвращает ноль. Вот синтаксис этого метода: oCollection.GetKey(eIndex) В табл. 11.14 перечислены возвращаемые методом значения. Таблица 11.14. Значения, возвращаемые методом GetKey
Метод RemoveМетод удаляет элемент из коллекции. Вот его синтаксис: oCollection.Remove(eIndex) Параметр eIndex может быть либо числовым значением индекса элемента, либо наименованием ключа. При удалении элемента из коллекции значение свойства Count уменьшается на единицу; так же на единицу уменьшаются индексы для всех элементов, расположенных в коллекции после удаляемого элемента. ПрименениеПрименение коллекций позволит вам решить множество проблем, которые
возникают при хранении данных в массивах. Простота использования и
объектно-ориентированный подход являются определяющими факторами в
пользу применения коллекций.
LOCAL loForm, loItem, lnTop loForm = CREATEOBJECT("myForm") lnTop=0 FOR EACH loItem IN loForm.myCollection TRY loItem.Top = lnTop lnTop=lnTop + 20 ? loItem.Name CATCH ENDTRY ENDFOR loForm.Show(1) DEFINE CLASS myForm AS Form AllowOutput=.F. AutoCenter=.T. ADD OBJECT myTextBox1 AS TextBox ADD OBJECT myTextBox2 AS TextBox ADD OBJECT myButton1 AS CommandButton ADD OBJECT myButton2 AS CommandButton ADD OBJECT myCollection AS col1 ENDDEFINE DEFINE CLASS col1 AS Collection PROCEDURE Init FOR i = 1 TO THISFORM.Objects.Count THIS.Add(THISFORM.Objects(m.i)) ENDFOR ENDPROC ENDDEFINE Класс EmptyКласс Empty используется для создания объектов, предназначенных для хранения данных. В отличие от ранее рассмотренных классов, этот класс не может использоваться как родительский при создании пользовательских классов. Он не содержит никаких свойств и методов; вы можете добавлять новые свойства в объекты этого класса, используя функцию ADDPROPERTY(). Удалить добавленное в этот объект свойство можно, используя функцию REMOVEPROPERTY(). Объект — экземпляр класса Empty может быть создан командой SCATTER … NAME: SELECT MySessionTable SCATTER FIELDS CookieText, SessionId NAME oCustomer ADDITIVE ? oCustomer.CookieText ? oCustomer.SessionId
|