Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / FoxPro, Visual FoxPro Новый топик    Ответить
 Свойство объекта и макроподстановка  [new]
_usa__83_
Member

Откуда:
Сообщений: 249
День добрый!

Очень "начинающий" вопрос. Вот есть объект "А1" некоторого класса "А", у него есть свойство
"b". Очень бы хотелось чтоб можно было бы писать в методах этого класса что-т типа
"INDEX ON A1.b ...." или "SET FILTER &This.b ...." и т.д. и т.п. Но что-т не "&" не "()" не даже "&()" не
получается.... Приходится всегда создавать переменную "LOCAL b ; b=This.b ; SET FILTER &b ..."

Вообщем как использовать члены-данные в выражениях для команд SET FILTER, INDEX ON, SET
RELATION и т.д.

Пасиба
9 ноя 10, 11:47    [9746868]     Ответить | Цитировать Сообщить модератору
 Re: Свойство объекта и макроподстановка  [new]
проходящий.
Guest
_usa__83_,
у Вас сам подход неправильный, наступаете на одни из самых распространенных граблей.
1. Настройка set filter и выражение в индексе - глобальные.
2. Ссылки this* - локальные для данного конкретного объекта, у которого, к тому же, еще и ограниченная область видимости.
3. Ссылок на отдельные свойства объектов не бывает.

Резюме: не пытайтесь использовать в этих командах ссылки и переменные, используйте значения.
9 ноя 10, 11:58    [9746953]     Ответить | Цитировать Сообщить модератору
 Re: Свойство объекта и макроподстановка  [new]
Игорь Горбонос
Member

Откуда: Днепропетровск
Сообщений: 4236

> Автор: проходящий.
> _usa__83_,
> у Вас сам подход неправильный, наступаете на одни из самых распространенных граблей.
> Резюме: не пытайтесь использовать в этих командах ссылки и переменные, используйте значения.

+1
Потом нужно парсить выражения наложенного фильтра и изменять то что изменилось.
+ примерно так:
Local sOldFilters As String, sNameField As String, sNameColumn As String, sValue As String
Local sTypeFilterColumn As String, sCharEnd As String, sCharStart As String
Local sCond As String, nCountConditions As Long, bIsFind  As Boolean
bIsFind  = .F.
Try
 sOldPoint = Set("Point")
 Set Point To [.]
 sOldFilters = Filter(Thisform.exgrid1.RecordSource)
 Select raw_fact
 CurrRecNo = Recno()
 sNameField  = Getwordnum(This.Tag, 1, "^")
 sNameColumn = Getwordnum(This.Tag, 2, "^")
 sValue = This.List(This.ListIndex)

* Ищем столбец курсора по которому будем фильтровать и определяем его тип, для правильного оформления условия фильтра
 Afields(arrF, Thisform.exgrid1.RecordSource)
 If Type("arrF[1]")#"U" Then
  nPos = Ascan(arrF, m.sNameField, -1, -1, 1, 1+8)
  If nPos != 0 Then
   sTypeFilterColumn = arrF(nPos,2)
  Else
   sTypeFilterColumn = "C"
  Endif
 Endif
* По определенному типу столбца, определяем символ ограничитель
 Do Case
 Case Inlist(sTypeFilterColumn, "C", "V")
  sCharStart = "["
  sCharEnd = "]"
 Case  Inlist(sTypeFilterColumn, "D", "T")
  sCharStart = "{"
  sCharEnd = "}"
 Case  Inlist(sTypeFilterColumn, "I", "Y", "B", "F", "N", "L")
  sCharStart = "  "
  sCharEnd = "  "
 Endcase
 If Len(sOldFilters) > 1 Then
* Если фильтр не пустой, проверяем, что наше поле есть уже в фильтре и устанавливаем новое значение
  nCountConditions = Alines(arrFilters, sOldFilters,1+4, ".AND.")
  sOldFilters = ""
  If nCountConditions > 0 Then
* В массиве из условий фильтра пробуем найти свое
   For i = 1 To nCountConditions
*    If Atc(sNameField, arrFilters(i)) != 0 Then
    If Len(sNameField) <= Len(arrFilters(i)) Then
     If Lower(sNameField) == Lower(Left(arrFilters(i), Len(sNameField))) Then
      bIsFind = .T.
* Если нашли наше поле, смотрим, что нужно делать. Поменять условие или убрать вообще
      If sValue != "(Все)" Then
* Если выбрали отобразить всё - удаляем условие, просто пропускаем это условие
* Если выбрали другое значение - перестраиваем условие
       sCond = sNameField + " = " + sCharStart + sValue + sCharEnd + " and "
*  Проверяем, если тип поля числовой, заменяем все запятые на точки
       If Inlist(sTypeFilterColumn, "I", "Y", "B", "F", "N", "L")
        sOldFilters = Chrtran(sCond, ",", ".")
       Endif
       sOldFilters = sOldFilters + sCond
      Endif
     Else
      sOldFilters = sOldFilters + arrFilters(i) + " and "
     Endif && If sNameField == Left(arrFilters(i), Len(sNameField)) Then
    Else
     sOldFilters = sOldFilters + arrFilters(i) + " and "
    Endif && If Len(sNameField) <= Len(arrFilters(i)) Then
   Next i
   If Len(sOldFilters) > 5 Then
    sOldFilters = Left(sOldFilters, Len(sOldFilters) - 5)
   Endif
   If !bIsFind And sValue != "(Все)" Then
    sCond = sNameField + " = " + sCharStart + sValue + sCharEnd
*  Проверяем, если тип поля числовой, заменяем все запятые на точки
    If Inlist(sTypeFilterColumn, "I", "Y", "B", "F", "N", "L")
     sCond = Chrtran(sCond, ",", ".")
    Endif
    sOldFilters = sOldFilters + " and " + sCond
   Endif
  Else
*  Количество условий пустое, просто добавляем
   sOldFilters = sNameField + " = " + sCharStart + sValue + sCharEnd
  Endif
 Else
  If sValue != "(Все)" Then
   sOldFilters = sNameField + " = " + sCharStart + sValue + sCharEnd
  Endif
 Endif
 Set Point To (sOldPoint)
* Если строка фильтра заполнена, применяем её
 Select(Thisform.exgrid1.RecordSource)
 Set Filter To
 If Len(sOldFilters) > 3 Then
*  sOldFilters = Chrtran(sOldFilters, ",", ".")
  Set Filter To &sOldFilters
 Endif
 sOldFilters = "Thisform.Exgrid1." + sNameColumn + ".Header1.ForeColor = " + Iif(sValue != "(Все)", "Rgb(0,0,255)", 
"Rgb(0,0,0)")
 &sOldFilters
 sOldFilters = "Thisform.Exgrid1." + sNameColumn + ".SetFocus()"
 &sOldFilters
Catch To oErr
 Set Point To (sOldPoint)
 If g_debug Then
  m.lcmess='('+Alltrim(Str(oErr.ErrorNo))+') '+Trim(oErr.Details) + Chr(10) ;
   + 'Сообщение: ' + Alltrim(oErr.Message) + Chr(10) ;
   + 'Функция: ' + Alltrim(oErr.Procedure) + Chr(10) ;
   + 'Строка №' + Alltrim(Str(oErr.Lineno)) + Chr(10) ;
   + 'Код в строке: ' + Alltrim(oErr.LineContents) + Chr(10) ;
   + 'message:' + Message() + Chr(10) ;
   + 'sOldFilters = ' + sOldFilters
  Messagebox(m.lcmess,0,'Ваше соединение вернуло ошибку: ',30000)
 Endif
Endtry


Posted via ActualForum NNTP Server 1.4

9 ноя 10, 12:16    [9747134]     Ответить | Цитировать Сообщить модератору
 Re: Свойство объекта и макроподстановка  [new]
Dima T
Member

Откуда:
Сообщений: 15279
Макроподстановки лучше пользовать по минимуму, но для описанных случаев без них никак. Причем пользовать только так:
_usa__83_
Приходится всегда создавать переменную "LOCAL b ; b=This.b ; SET FILTER &b ..."

Как я понимаю макроподстановка работает так: если встречается символ & то фокс читает все буквы-цифры после него и проверяет что есть такая строковая переменная и заменяет этот кусок на содержимое переменной, т.е. точка это символ которого не может быть в имени переменной, поэтому он на ней останавливается.
Если переменной с таким именем не существует или она не строковая, то макроподстановки не происходит.
Запусти этот код, думаю понятно будет как оно работает:
clear
X = '2222'
? '111&X.333'
? '111&X333'
X = 2222
? '111&X.333'
9 ноя 10, 17:25    [9749875]     Ответить | Цитировать Сообщить модератору
Все форумы / FoxPro, Visual FoxPro Ответить