Перейти к содержимому

Как сделать справочник на c

  • автор:

Подчиненный справочник 1С

В прикладных задачах иногда возникают ситуации, когда элемент какого-нибудь справочника должен быть жестко подчинен элементу другого справочника. Например, у контрагентов могут существовать договоры, которые заключены с организацией, ведущей учёт. Тогда, экземпляр справочника Договоры контрагента должен быть подчинен справочнику Контрагенты, поскольку, мы не можем создать договор сам по себе, договор должен быть привязан к конкретному контрагенту. Для реализации подобных задач необходим подчиненный справочник 1С. В выше приведенном случае, справочник Договоры контрагента станет подчинен справочнику Контрагенты. А справочник Контрагенты будет являться владельцем справочника Договоры контрагента.

Конструируем подчиненный справочник 1С

Для того, чтобы из справочника 1С сделать подчиненный справочник, достаточно в редакторе справочника на закладке Владельцы указать владельца этого справочника.

Подчиненный справочник 1С

После этого, справочник с заполненным списком на закладке Владельцы станет подчиненный, а справочник (или справочники) из списка на этой закладке будут владельцами данного справочника.

Подчиненный справочник 1С

После таких манипуляций, нельзя создать этот справочник (в рассматриваемом примере – ДоговорыКонтрагента) без указания владельца (Контрагента).

Если мы попробуем создать, элемент справочника ДоговорыКонтрагента, то поле, в котором следует указать контрагента-владельца будет обязательным для заполнения.

Подчиненный справочник 1С

Заметьте, это поле называется Владелец и является стандартным реквизитом справочника.

Стандартный реквизит справочника 1С

Этот реквизит стал активным, тогда, когда мы указали владельца справочника на закладке Владельцы.

В тоже время, на форме элемента справочника-владельца появилась команда с названием подчиненного справочника.

Подчиненный справочник 1С

После выполнении этой команды, откроется форма списка с элементами подчиненного справочника, у которых владелец ссылка на открытый элемент справочника Контрагенты.

Подчиненный справочник 1С

Программное создание элемента подчиненного справочника

Разберем программное создание элемента подчиненного справочника. Оно выполняется при помощи метода менеджера справочник СоздатьЭлемент. Только, в случае подчиненных справочников обязательно нужно указать владельца!

Например, создадим обработку, на управляемой форме которой разместим реквизиты Владелец (тип ссылка на справочник Контрагент) и Название договора, а также команду Создать подчиненный справочник.

Форма обработки 1С

При выполнении этой команды, будем создавать экземпляр справочника Договоры контрагента, который подчинен указанному владельцу.

&НаСервере Процедура СоздатьПодчиненныйСправочникНаСервере() НовыйДоговор = Справочники.ДоговорыКонтрагента.СоздатьЭлемент(); НовыйДоговор.Наименование = НазваниеДоговора; НовыйДоговор.Владелец = Владелец; НовыйДоговор.Записать(); КонецПроцедуры &НаКлиенте Процедура СоздатьПодчиненныйСправочник(Команда) Если Не ПроверитьЗаполнение() Тогда Возврат; КонецЕсли; СоздатьПодчиненныйСправочникНаСервере(); КонецПроцедуры 

В клиентской процедуре используется проверка заполнения. Подробнее о проверке читайте в этой статье:

Выбор элементов подчиненного справочника на управляемой форме

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

Например, у документа Продажа товаров существуют реквизиты Контрагент и Договор контрагента соответствующих типов.

Справочники 1С

Для того, чтобы в реквизите Договор контрагента можно было выбрать только договоры указанного контрагента, следует в палитре свойств реквизита объекта у свойства Связи параметров выбора сделать настройку, в которой указать, что реквизит Контрагент используется при выборе значений в качестве владельца.

Справочники 1С

Справочники 1С

После таких настроек, в поле ввода Договоры контрагента можно выбрать только договоры, указанного контрагента.

Справочники 1С

Если же мы создадим реквизит управляемой формы с ссылкой на подчиненный справочник, то у этого реквизита не будет такого же свойства, как и у реквизита объекта.

Реквизит управляемой формы 1С

Для того, чтобы отбор работал, следует у элемента формы, который связана с реквизитом для подчиненного справочника, заполнить свойство Связи параметров выбора.

Реквизит управляемой формы 1С

Поиск среди подчиненных справочников

Для того, чтобы найти какой-то элемент среди подчиненных справочников, при помощи методов менеджера справочника НайтиПоНаименованию, НайтиПоКоду и НайтиПоРеквизиту следует использовать параметр Владелец этих методов.

Например, в случае поиска по наименованию, код будет следующим.

Договор = Справочники. ДоговорыКонтрагента.НайтиПоНаименованию(НазваниеДоговора,Истина,,Владелец); 

Где НазваниеДоговора – это наименование элемента справочника, который ищется.

Владелец – это ссылка на справочник владелец.

Подчиненный справочник 1С или табличная часть?

Часто возникает вопрос: чем отличается подчиненный справочника от табличной части. Основной ответ, тем что у элемента подчиненного справочника имеется ссылка на этот элемент, а у строки табличной части такой ссылки нет.

Подробно, о том, что выбрать при разработке подчиненный справочник или табличную часть читайте по этой ссылке на сайте its.1c.ru:

Читайте также по теме:

Более подробно и основательно начальные вопросы программирования в 1С есть вы можете изучить в
Книга «Программировать в 1С за 11 шагов»

Изучайте программирование в 1С в месте с моей книгой «Программировать в 1С за 11 шагов»

Программировать в 1С за 11 шагов

Книга написана понятным и простым языком — для новичка.

  1. Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
  2. Научитесь понимать архитектуру 1С;
  3. Станете писать код на языке 1С;
  4. Освоите основные приемы программирования;
  5. Закрепите полученные знания при помощи задачника

О том как разрабатывать под управляемым приложением 1С, читайте в книге Книга «Основы разработки в 1С: Такси»

Отличное пособие по разработке в управляемом приложении 1С, как для начинающих разработчиков, так и для опытных программистов.

Основы разработки в 1С такси

  1. Очень доступный и понятный язык изложения
  2. Книга посылается на электронную почту в формате PDF. Можно открыть на любом устройстве!
  3. Поймете идеологию управляемого приложения 1С
  4. Узнаете, как разрабатывать управляемое приложение;
  5. Научитесь разрабатывать управляемые формы 1С;
  6. Сможете работать с основными и нужными элементами управляемых форм
  7. Программирование под управляемым приложением станет понятным

Промо-код на скидку в 15% — 48PVXHeYu

Эти книги, плюс книга по программированию оперативного учета имеются в едином комплекте: комплект книг по разработке в 1С.
Только для читателей моего блога,
промо-код на скидку в 300 рублей на весь комплект: blog


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

можно оплатить вручную:

Вступайте в мои группы:

Предложение let (справочник по C#)

В выражении запроса иногда требуется сохранить результат вложенного выражения, который будет использоваться в последующих предложениях. Это можно сделать с помощью ключевого слова let , которое создает новую переменную диапазона и инициализирует ее, используя результат предоставленного выражения. После инициализации с использованием этого значения такую переменную диапазона нельзя использовать для хранения других значений. Тем не менее если переменная диапазона хранит запрашиваемый тип, к ней можно выполнять запросы.

Пример

В следующем примере показываются два способа использования let :

  1. Создание перечисляемого типа, к которому можно выполнять запросы.
  2. Реализация запроса с однократным вызовом ToLower для переменной диапазона word . Если ключевое слово let не используется, потребуется выполнять вызов ToLower в каждом предикате предложения where .
class LetSample1 < static void Main() < string[] strings = < "A penny saved is a penny earned.", "The early bird catches the worm.", "The pen is mightier than the sword." >; // Split the sentence into an array of words // and select those whose first letter is a vowel. var earlyBirdQuery = from sentence in strings let words = sentence.Split(' ') from word in words let w = word.ToLower() where w[0] == 'a' || w[0] == 'e' || w[0] == 'i' || w[0] == 'o' || w[0] == 'u' select word; // Execute the query. foreach (var v in earlyBirdQuery) < Console.WriteLine("\"\" starts with a vowel", v); > // Keep the console window open in debug mode. Console.WriteLine("Press any key to exit."); Console.ReadKey(); > > /* Output: "A" starts with a vowel "is" starts with a vowel "a" starts with a vowel "earned." starts with a vowel "early" starts with a vowel "is" starts with a vowel */ 

См. также

  • Справочник по C#
  • Ключевые слова запроса (LINQ)
  • LINQ в C#
  • LINQ
  • Обработка исключений в выражениях запросов

Технология создания форм для работы со справочниками

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

  1. Использование в работе шаблон проектирования Модель-Представление-Контроллер (MVС)
  2. Динамическое создание форм, как это делаю я.

Эти две темы практически не отделимы друг от друга — по одной простой причине — если вы не пользуетесь MVС, рано или поздно, в сравнительно большом проекте, вы начнете писать жуткий «макаронный» код, в котором будете путаться сами. Что бы этого избежать — используйте хорошие шаблоны программирования.

Все примеры, которые приведены в данной статье опираются на средства разработки компании Borland — Borland Builder C++, но по сути могу применяться в любой системе вне зависимости от языка программирования. BCB используется здесь только потому, что на нем пишет человек, который попросил написать данную статью.

И так MVС. Что это такое, с чем ее едят и почему именно вам надо этот шаблон использовать? Все очень просто. основной принцип использования MVС заключается в разделении кода — если вы разделяете код, который получает данные из базы, от кода коорый эти данные обрабатывает и отдельно формируете код, который результат этой обработки показывает — поздравляю — вы используете MVС. Большинство удачных программных инструментов спроектировано таким образом, что следовать этому шаблону в них достаточно просто, легко и интуитивно понятно. Но как раз таки BCB и Delphi к таким системам не относятся (за что, я думаю, их создатели будут гореть в Аду — в специально для них созданном 10 круге), потому что в них чрезвычайно просто и легко писать «макаронный» быдлокод — когда все получение данных, их обработка и вывод запихивается в один единственный класс единственной формы, на которую горе программист накидал под сотню контролов — и весь этот, с позволения сказать, код размером в несколько тысяч строк компилируется в исполнимый файл и гордо называется «продуктом».

В принципе ничего конечно страшного в этом нет — если конечно не вам это все в последствии обслуживать и поддерживать. Потому что, в процессе обслуживания и поддержки работающей программы так или иначе приходится ее расширять, дорабатывать и… и вот тут то наступает армагедец. Потому что, через несколько месяцев уже плохо помниться зачем была написана та функция — которая вызывается по 20 раз в разных местах, и почему в некоторых местах в место этой функции вызывается совершенно другой код…ну и так далее. Те, кому приходилось поддерживать «продукты» жизнедеятельности таких вот «программистов» меня поймут.

Как реализовать все это на практике? Спроектируем небольшой модуль системы — предположим наш модуль будет реализовать следующую функциональность:

  1. Вывод и отображение записей различных справочников.
  2. Добавление, редактирование и удаление выбранных записей.
  3. Предоставление единого интерфейса для получения записей справочников (списки, деревья и пр.) в любой точке приложения.

Для начала вполне достаточно. Если использовать стандартный подход — то обычно создается форма, туда запихиваются нужные контролы и компоненты — потом создаются еще форма(а зачастую и не одна) для редактирования и добавления. Выборка данных из справочников выполняется в каждой точке приложения независимо.

Как это сделать с точки зрения MVС? Необходимо спроектировать четыре класса — класс-контроллер, класс доступа к данным, класс-форма основная и класс-форма добавления редактирования. Так как справочник по-английски Reference то соответственно классы лично я именую следующим образом:

  1. TRefernceController — класс контроллера, наследует от общего класса контроллера (если нужно);
  2. TmfMain — класс основной формы, наследует от TForm (BCB);
  3. TfmAddEdit — класс вспомогательной формы, наследует от TForm (BCB);
  4. TdmMain — модуль данных, наследует от TDataModule (BCB).

Естественно, наследование классов зависит от вашего конкретного приложения — я взял простейший вариант, что бы не слишком углубляться и не путаться. Название модулей — тоже зависит от того, какая система наименований принята у вас. Например, TmfMain — у меня имеет название любая основная форма модуля, но впрочем, это детали и я оставляю это на ваше рассмотрение.

Объевление класса контроллера может выглядеть примерно таким образом:

#ifndef loginH
#define loginH
#include
#include
#include
#include
#include
#include
#include
#include «main.h» //подключаем заголовочные файлы форм
#include «addedit.h»

class TReferenceController : public TGlobalController //если нужно, наследуем от своего общего класса
{
TfmMain * fmMain ;
TfmMain * dmMain ;
. //другие закрытые объявления
public :
__fastcall TRefernceController ( TConnection * db ) ;
void __fastcall getList ( TStrings * list, const int index ) ;
. //другие открытые методы
} ;
#endif

Как видим ничего особо сложного тут нет. Конкретная реализация контроллера зависит от задач приложения, но суть от этого не меняется — задача класса — обеспечивать всю работу с объектами, скрывая от пользователя-приложения все детали и тонкости. Основной момент — в конструктор класса я передаю указатель на существующее в приложении подключение — что бы было чем инициализировать модуль подключения к БД.

Класс модуля данных, в свою очередь, обеспечивает подключение к БД, получение необходимых данных, операции создания, редактирования и удаления данных в таблицах.

Его объявление может выглядеть примерно таким образом:

//—————————————————————————
class TdmMain : public TDataModule
{
__published : // IDE-managed Components
TADOConnection * adoConnect ;
TDataSource * dsListOrder ;
TADOQuery * adoListOrder ;
private : // User declarations
int UserId ;
//другие закрытые методы и свойства
public : // User declarations
__fastcall TdmMain ( TComponent * Owner, const bool visibleForm = true ) ;
__fastcall TdmMain :: TdmMain ( TComponent * Owner, TConnection * db ) ;
void __fastcall getListReference ( TStrings * list ) ;
//другие открытые методы

В описании форм нет ничего особенного, поэтому код приводить считаю тут излишним.

Общий алгоритм выглядит следующим образом:

  1. Приложение инициализирует модуль;
  2. Создает объект класса TReferenceController, путем вызова его конструктора и передав ему указатель на открытое соединение с БД;
  3. В качестве параметров конструктора создается объект модуля данных;
  4. Если установлен флаг создания формы — создаем форму.

Пример кода конструктора контроллера:

__fastcall TReferenceController :: TReferenceController ( TConnection * db, const bool visibleform ) : dmMain ( NULL ,db )
{
//если нужно — создаем форму, заполняем и показываем ее модально
if ( visibleForm )
{
fmMain = new TfmMain ( NULL ) ;
dmMain — > getListTab ( fmMain — > PageContorl, 0 ) ; //загружаем табы справочников и устанавливаем индекс
fmMain — > ShowModal ( ) ;
}
}

Думаю основная идея вполне понятна. Естественно, использование MVC немного усложняет жизнь на первом этапе — но зато значительно упрощает ее в дальнейшем.

Если же, идея с использованием контроллера все же вам кажется чересчур сложной — вы можете использовать упрощенный вариант — две формы и модуль данных. В таком случае получение, обработка и запись данных реализуется в модуле данных (dmMain) и соответственно там располагаются все компоненты для работы с БД. Формы в свою очередь реализуют отображение и обработку ввода данных.

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

CREATE TABLE [ dbo ] . [ Spr_Podr ] (
[ Kod ] [ int ] IDENTITY ( 1 , 1 ) NOT NULL , автоинкрементный
[ KodMR ] [ int ] NULL , код места работы
[ MR ] [ nvarchar ] ( 150 ) COLLATE Cyrillic_General_CI_AS NULL , название места работы
[ prMR ] [ nvarchar ] ( 250 ) COLLATE Cyrillic_General_CI_AS NULL , название места работы для формирования приказа
[ arh ] [ int ] NOT NULL признак записи в архиве 0 или 1
) ON [ PRIMARY ]

CREATE TABLE [ dbo ] . [ Spr_Slugb ] (
[ Kod ] [ int ] IDENTITY ( 1 , 1 ) NOT NULL , автоинкрементный
[ KodPodr ] [ int ] NULL , код службы ( отдела )
[ Podr ] [ nvarchar ] ( 250 ) COLLATE Cyrillic_General_CI_AS NULL , название службы ( отдела )
[ arh ] [ int ] NOT NULL признак записи в архиве 0 или 1
) ON [ PRIMARY ]

CREATE TABLE [ dbo ] . [ Spr_PodPodr ] (
[ Kod ] [ int ] IDENTITY ( 1 , 1 ) NOT NULL , автоинкрементный
[ KodPPodr ] [ int ] NULL , код подотдела
[ PodPodr ] [ nvarchar ] ( 255 ) COLLATE Cyrillic_General_CI_AS NULL , название подотдела
[ arh ] [ int ] NOT NULL признак записи в архиве 0 или 1
) ON [ PRIMARY ]

CREATE TABLE [ dbo ] . [ SprDolg ] (
[ id ] [ int ] IDENTITY ( 1 , 1 ) NOT NULL , автоинкрементный
[ Kod ] [ int ] NULL , код должности
[ Dolg ] [ nvarchar ] ( 150 ) COLLATE Cyrillic_General_CI_AS NULL , название должности
[ Dolg_K ] [ nvarchar ] ( 150 ) COLLATE Cyrillic_General_CI_AS NULL , название должности для карточки
[ K_go ] [ nvarchar ] ( 150 ) COLLATE Cyrillic_General_CI_AS NULL , название должности — кого
[ K_mu ] [ nvarchar ] ( 150 ) COLLATE Cyrillic_General_CI_AS NULL , название должности — кому
[ K_m ] [ nvarchar ] ( 150 ) COLLATE Cyrillic_General_CI_AS NULL название должности — ким
[ arh ] [ int ] NOT NULL признак записи в архиве 0 или 1
) ON [ PRIMARY ]

как видно, в целом справочники похожи — они отличаются только количеством текстовых полей, которые записываются и читаются в БД, т.е. три поля во всех справочниках однотипны — это поля id (Kod), Kod*, arh — первые два — числовые значения, последнее — может содержать либо 0 либо 1. Поле id автоинкремент — т.е. поле ввода ему не нужно, оно может только отображаться. Хотя бывают задачи, когда нужно иметь возможность устанавливать его вручную, тогда нужно реализовывать отдельную операцию — но в данном случае нет такой необходимости. Поле Kod пользователь должен иметь возможность устанавливать руками — т.е. для него мы предусматриваем отдельное текстовое поле ввода. Для поля arh нам достаточно чекбокса — так как оно может иметь только два значения. И как минимум, в каждом справочнике должно быть хотя бы одно текстовое поле. Структура конечно так себе, тут ничего не скажешь. Человек который ее проектировал — сложной судьбы человек, мягко говоря. 🙂 Но тут я не буду останавливаться на принципах проектирования БД, скажу только, что если вы реализуете подобное — старайтесь соблюдать единообразие. Если во всех справочниках присутствует однотипные поля — используйте для них и одинаковые названия. Не должно в одной из таблиц ключевое поле в одном случае Kod а во втором id. Не усложняйте сами себе жизнь.

Что бы нормально работать со справочниками — я бы рекомендовал добавить в БД две дополнительные таблицы, задача которых — хранить метаданные для отображения. В первой из них храните идентификатор справочника, название таблицы справочника, возможно название справочника для отображения (если система одноязычная, либо название для языка по умолчанию) и другие параметры, которые возможно вам понадобятся, а во второй таблице соответственно идентификатор записи, идентификатор справочника, имя поля и название поля для отображения. Ну и другие параметры, которые помогут вам настраивать отображение каждого из полей.Таблицы естественно должны быть связаны по идентификатору справочника. Если вы сердцем чуете что естественные ключи лучше чем искусственные — можете использовать в качестве ключа название таблицы справочника. Это на любителя.

В таком случае для каждого справочника задача упрощается максимально. После того, как таблицы созданы и заполнены — следующий шаг — создание основной формы. Помните, выше мы говорили о контроллере — так вот проще всего делать это через него. Если же эта модель вам кажется слишком сложной — то можно обойтись и без этого. В первую очередь определяемся — как будет происходить загрузка наших данных. Так как справочников может быть один и больше — используем TPageControl. Располагаем его на форме, называем pcMain, настраиваем нужные параметры. В принципе ничего особо сложного в этом нет — поэтому все дальнейшее я буду иллюстрировать кодом.

Код основной формы:

#include
#pragma hdrstop

#include «mainfm.h»
#include «addedit.h»
//—————————————————————————
#pragma package(smart_init)
#pragma resource «*.dfm»
TfmMain * fmMain ;
//—————————————————————————
__fastcall TfmMain :: TfmMain ( TComponent * Owner )
: TForm ( Owner ) ,dmMain ( Owner )
{
//тут пишете код, в котором инициализируете подключение к БД. Если БД уже подключена — используется другой конструктор
}
__fastcall TfmMain :: TfmMain ( TComponent * Owner, TADOConnection * db )
: TForm ( Owner ) ,dmMain ( Owner,db )
{
dmMain — > loadPages ( this — > pgMain ) ;
dmMain — > loadReference ( getCurrentGrid ( ) ) ;
}

//—————————————————————————
TDBGrid * __fastcall TfmMain :: getCurrentGrid ( )
{
if ( pgMain — > ActivePageIndex == — 1 ) return ;
TDBGrid * db = NULL ;
for ( int i = 0 ; i < this - >ComponentCount ; ++ i ) {
if ( this — > Components — > ClassName ( ) ! = «TDBGrid» ) continue ;
db = dynamic_cast < "TDBGrid" >( this — > Components ) ;
if ( db — > Parent == pgMain — > ActivePage ) break ;

}
return db ;
}
void __fastcall TfmMain :: pgMainChange ( TObject * Sender )
{
dmMain — > loadReference ( getCurrentGrid ( ) ) ;
}
//—————————————————————————
void __fastcall TfmMain :: FormDblClick ( TObject * Sender )
{
TStringList * ls ;
TfmAddEdit * fm ;
try {
fm = new TfmAddEdit ( NULL ) ;
//получаем перевичный ключ
fm — > id = dmMain — > adoQuery — > Fields — > FieldByNumber ( 0 ) — > AsInteger ;
//тут получаем параметры наших полей из доптаблицы в список
ls = new TStringList ;
dmMain — > loadReferenceFields ( ls ) ;
//тут обрабатываем наш список — как создавать объекты и инициализировать их параметры
// показано выше. не забывайте проверять высоту формы и высоту объектов
.
}
__finally {
if ( fm ) delete fm ;
if ( ls ) delete ls ;
}

//—————————————————————————
class TdmMain : public TDataModule
{
__published : // IDE-managed Components
TADOConnection * adoConnect ;
TADOQuery * adoQuery ;
TDataSource * dsQuery ;
TADOQuery * adoExecute ;
private : // User declarations
public : // User declarations
__fastcall TdmMain ( TComponent * Owner ) ;
__fastcall TdmMain ( TComponent * Owner, TADOConnection * db ) ;
void __fastcall loadPages ( TPageControl * pg, const int index = 0 ) ;
void __fastcall loadReference ( TDBGrid * gb ) ;
void __fastcall loadReferenceFields ( TStrings * ls ) ;
} ;
//—————————————————————————
extern PACKAGE TdmMain * dmMain ;
//—————————————————————————
#endif
//—————————————————————————

#include
#pragma hdrstop

}
void __fastcall TdmMain :: loadPages ( TPageControl * pg, const int index )
{
TTabSheet * tab ;
adoExecute — > SQL — > LoadFromFile ( «loadreferense.sql» ) ;
adoExecute — > Active = true ;
while ( ! adoExecute — > Eof ) {
tab = new TTabSheet ( pg ) ;
tab — > Name = adoExecute — > FieldByName ( «tablename» ) — > AsString ;
//так же настраиваем другие параметры если надо
TDBGrid * grid = new TDBGrid ( tab ) ;
grid — > Name = «gd» + tab — > Name ;
grid — > Parent = tab ;
grid — > Tag = adoExecute — > FieldByName ( «referenceid» ) — > AsInteger ;
grid — > Align = alClient ;
grid — > OnDblClick = fmMain — > OnDblClick ; //устанавливаем обработчик двойного клика
adoExecute — > Next ( ) ;
}
if ( pg — > PageCount > index ) pg — > ActivePageIndex = index ;
else pg — > ActivePageIndex = 0 ;
}
void __fastcall TdmMain :: loadReference ( TDBGrid * gb )
{
if ( ! gb ) return ;
adoQuery — > Active = false ;
adoQuery — > LoadFromFile ( gb — > Name + «.sql» ) ;
adoQuery — > Active = true ;
gb — > DataSource = dsQuery ;
}
//—————————————————————————

Как видно в коде, практически все компоненты создаются динамически, и в процессе работы я им присваиваю необходимые обработчики. Значительная часть кода опущена, так как она строится по тем же принципам, что и приведенный. Естественно в модуле данных надо реализовать сохранение изменений и т.п., но я думаю что вы с этим сможете справится сами. Ничего сложного. Кроме того — если вы обратили внимание — запросы к БД загружаются из файлов. Я считаю подобный подход более практичным — когда запросы хранятся отдельно от приложения. Хотя конечно все еще зависит от конкретных задач и от ваших предпочтений.

Надеюсь что этот материал оказался полезным — если есть вопросы, задавайте в комментариях.

Как сделать справочник на c

Добрый день, уважаемые форумчане!

Я реализую программу «Телефонный справочник».

Проблема возникает при считывании данных с консоли в поля структуры.
Хотелось бы, чтобы данные для каждого поля считывались как цельная строка, которая в дальнейшем приводилась к типу char[] / char*

Заранее благодарю за помощь.

 #include "stdio.h" #include "iostream" #include "string.h" using namespace std; struct Persone < char *firstname; char *lastname; char *callnumber; Persone *next, *head; >; void Delete (Persone *Pers) < if (Pers ->head == NULL) < cout if (Pers -> head != NULL) head; //элемент для показа в консоли Persone *Temp_stack = Pers -> head -> next; // сохраняем ссылку на следующий элемент cout firstname lastname callnumber head; Pers -> head = Temp_stack;//голова стека указывает на следующий элемент cout > void addElem (char *firstname, char *lastname, char *callnumber, Persone *&pers) < Persone *temp = new Persone; temp ->firstname = firstname; temp -> lastname = lastname; temp -> callnumber = callnumber; //реализация стека temp -> next = pers -> head; pers -> head = temp; > char *Get_Data (string &sstr) < char* cstr2 = new char[sstr.length()]; strcpy(cstr2, sstr.c_str()); for (int i = 0; i < sstr.length(); i++) cout void Show (Persone *per) < Persone *List = per ->head; while (List != NULL) < cout firstname lastname callnumber next; > if (per->head == NULL) < cout > void Input (Persone *&pers) < string f_n, l_n, c_n; cout void Menu () < cout void ClearList (Persone *per) < while (per ->head != NULL) < Persone *temp = per ->head -> next; delete per->head; per->head = temp; > > int main () < setlocale (LC_ALL, "russian"); //system ("color f2"); Persone *pers = new Persone; pers->head = NULL; cout 

DimitryLutsenko
Посмотреть профиль
Найти ещё сообщения от DimitryLutsenko

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *