Яндекс.Метрика

                            Вопросы и ответы, а также советы


Советы для разработчика

Таблица справочника (строки которой видны в правой части клиентского приложения, а не таблица на форме ввода)
     В справочниках есть ограничение на количество отображаемых символов? У меня почему-то больше 50 отсекается...

Программа формы ввода
 
Объекты на форме
     Когда двигаюсь по таблице есть ли функция указывающая на текущую строку?

  Приемы работы со справочниками
    
Как программно создать копию записи (карточки) справочника с изменениями некоторых значений?

Программа формы ввода.
  Чтение данных (в т. ч. из внешних источников).

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


Советы.

Оператор присвоения можно применять для множественного присвоения значений элементов одной колонки элементам другой (вместо применения присвоения значений в цикле).
Такое присвоение корректно:
Колонка1 := Колонка2; если обе колонки одного типа. Все значения Колонки2 будут присвоены элементам Колонки1, даже если в Колонке1 было другое количество элементов и другие значения.

Оптимизация производительности при чтении данных из таблиц справочников.

Часто бывает необходимо считывать значения из колонок таблицы в записях справочника. И первое что приходит в голову прочитать значения из колонки в цикле. Примерно так (приведенная функция читает значения ячеек одной колонки таблицы справочника во всех записях):
переменные
  число А; справочник(НекийСправочник) НК;
начало
  пока СледующееЗначение(НК) делать !перебор записей справочника
   !далее в цикле последовательно читаются значения всех ячеек из колонки таблицы
    цикл А от 1 до количествоСтрок(НК.Табл) делать
      Перем := НК.Табл.Кол1(А); !читается значение из одной ячейки непосредственно из записи
      !присвоение только для примера
    конец
  конец 
конец


И все было бы хорошо, если бы не перебирать много записей справочника (здесь "НекийСправочник"), а в нем не перебирать (для чтения) все ячейки колонки (колонок) в нем.
Запрос на чтение значения (НК.Табл.Кол1(А)) выполняется быстро, но если таких запросов огромное количество, то о высокой скорости выполнения вышеприведенной функции можно только мечтать.
Есть прием позволяющий выполнить эту функцию от 3 до 10 раз быстрее.
Вместо множества запросов для получения значений ячеек нужно выполнить один - считать всю колонку значений и присвоить эти значения локальной колонке (естественно, такого же типа).
После этого в цикле читать уже значения элементов (ячеек) локальной колонки, которая "сидит" в памяти и  поэтому производительность возрастает.

Переделать нашу гипотетическую функцию можно так:
переменные
  число А; справочник(НекийСправочник) НК;
  колонка(число)кКол1;
  !предполагаем, что колонка "Кол1" в таблице тоже числового типа
начало
  пока СледующееЗначение(НК) делать
   
кКол1 := НК.Табл.Кол1;
   !этот единственный запрос читает все значения колонки таблицы и
   !присваивает их локальной колонке
   !дальше чтение значений происходит из этой локальной колонки
    цикл А от 1 до количествоСтрок(кКол1) делать
      Перем := кКол1(А); !читается значение из локальной колонки
    конец
  конец 
конец

В начало

Когда двигаюсь по таблице есть ли функция указывающая на текущую строку?

Системная переменная СтрокаТаблицы (тип число) имеет значение текущей строки таблицы, в которую происходит ввод данных. Если фокус ввода не в таблице, то значение этой константы не определено.

В начало

Функция Импорт пытается читать данные из файла в переменные, но переменные при этом пустые.

Вопрос:
Написал процедуру импорта в справочник:

функция НажатаКнопка1
переменные
  строка с1,с2,с3,с5,с7,с8,с15,с10,с12;
  число с6,с9,с11;
  дата с4;
  справочник(ОМС) сОМС;
начало
  если Импорт("c:\spisok.csv",0) то
    пока Импорт(,1,0,";",С1,С2,С3,С4,с5,с6,с7,с8,с9,с10,с11,с12) делать
      ЗаписатьЗначение(Документ:=сОМС, Привязка:=Нет, Зависимость:=Нет,
                       Фамилия:=С1, Имя := С2, Отчество:=С3, ДатаРождения:=с4,
                       Пол:=с5, регион := встроку(с6), Город:=с7,
                       Улица:=с8, Дом:=встроку(с9), Корпус:=с10,
                       Квартира:=встроку(С11),
                       Серия:=ЧастьСтроки(с12,1,5),
                       Номер:=ЧастьСтроки(с12,7,6));
    конец
    Импорт(,2);
  конец
конец


Структура файла импорта следующая:
Аболина;Галина;Александровна;12.11.54;;46457000;г.Орехово-Зуево;ул.Иванова;11;;11;46 11 111111

При выполнении импорта переменные Сх остаются пустыми, но по записям
функция бегает, т.к. создаются пустые записи в справочнике.

Ответ:
В некоторые функции параметры передаются по ссылке, т.е. функциями в них загружаются значения, которые и возвращаются в вызывающую программу.
При компиляции локальные переменные не инициализируются, а, следовательно, при выполнении функция Импорт "не знает" какого они типа и поэтому не может заполнить их значениями.
Выход такой: локальные переменные необходимо инициализировать, т.е. надо не только указать их тип, но и присвоить им "пустое" значение. Для вышеприведенного примера это выглядит так:

переменные
  строка с1:="",с2:="",с3:="",с5:="",с7:="",с8:="",с15:="",с10:="",с12:="";
  число с6:=0,с9:=0,с11:=0;
  дата с4;
  справочник(ОМС) сОМС;
начало
 
с4 := ПустаяДата; !инициализация переменных типа дата
  .....

Инициализация локальных переменных нужна только если переменные предназначены для передачи в параметрах таких вот функций или когда переменная встречается в левой и правой частях выражения присвоения (напр., П := П + 5), для другого применения инициализация не нужна.

В начало

В справочниках есть ограничение на количество отображаемых символов? У меня почему-то больше 50 отсекается...

Это делается только при ОТОБРАЖЕНИИ строки в таблице справочников (это та таблица, строки которой видны в правой части клиентского приложения).
Ограничение только для отображения. Если строковое поле имеет количество символов большее чем 50, то они сохраняются в базе и в объекта формы ввода и в отчетах показываются все.
Как правило, 50-ти символов хватает чтобы уловить суть строки, а если надо посмотреть всю строку то можно открыть карточку (форму ввода).

А если более подробно, то эти 50 символов были сделаны не спроста.
Можно было бы еще в самом начале разработки Афины запихать строки в "безразмерное" поле. Такие типы данных есть в SQL базах (BLOB). Но их особенность в том, что по ним невозможен поиск. А поиск в данных, в т.ч. и в строковых - это основополагающая необходимость в базах данных.

Вот и пришлось делить строку на две части. Одна часть (первые 50 символов) записывается в базу в виде ограниченного количества символов, а другая "безразмерная", куда записывается остальная часть строки (если, конечно, она есть).
Такое извращение позволило пристрелить пару зайцев: и поиск по строкам организовать (правда, только по первым 50-ти символам), и сократить время формирования таблицы справочника.

В начало

Как программно создать копию записи (карточки) справочника с изменениями в некоторых значениях?

В программе формы должна быть переменная со ссылкой на запись-оригинал.
Записываете новую карточку, передавая в параметрах все значения из записи-оригинала, меняя некоторые
из значений на другие.

переменные
  справочник(справочник1) спр1, спрКопия;
начало
!в спр1 - ссылка на запись-оригинал (это может быть и поле взятое из структуры,
!в котором уже есть ссылка)

  ЗаписатьЗначение(Документ := спрКопия, Привязка := Нет, Зависимость := Нет,
                   поле1 := спр1.Поле1,
                   поле2 := спр1.Поле2,
                   Поле3 := 45, !меняем на другое значение
                   поле4 := спр1.Поле4, ...)
  !ВызватьФорму(Документ := спрКопия); !если нужно вызвать созданную копию
конец

В переменной "спрКопия" функция ЗаписатьЗначение возвращает ссылку на новую запись.
Если предполагается применять ф. ВызыватьФорму после создания копии, то параметры Привязка и Зависимость должны быть установлены так как показано в примере. Впрочем, в любом случае это должно быть так.
И еще важное: оригинал и копия должны быть определены отдельными переменными как показано в примере ("спр1" и "спрКопия"). Если, например, спр1 определен в структуре и его значение выбирает пользователь, то для записи новой карточки должна применяться другая переменная этого же типа справочника.

В начало

 

 
Hosted by uCoz