#ms-access #vba
#ms-access #vba
Вопрос:
У меня есть форма, которая будет генерировать отчет для рассылки. Форма открывает набор записей со всеми необходимыми полями. Я размышляю, как я могу передать этот набор записей в отчет, чтобы мне не нужно было снова открывать тот же набор записей.
Аналогично, иногда я также хочу передавать набор записей между формами (без отношения main / sub form), как я могу это сделать?
Еще один маленький вопрос, когда я открываю форму в представлении таблицы данных, она всегда очень большая. Как я могу ограничить его размер при открытии?
Спасибо!
Редактировать:
Чтобы было понятнее, скажем, у меня есть «ФОРМА», когда пользователь нажимает на нее кнопку, «Отчет» будет открыт. Я хочу, чтобы «Отчет» использовал набор записей, который уже создан (открыт) в «ФОРМЕ».
Также в «ФОРМЕ» есть текстовое поле, заполняемое пользователями, я также хочу показать его в «Отчете».
ПРАВКА2:
Я устал, но не могу вставить набор записей или заполнить поле в моем отчете из текстового поля в моей форме, очень раздражает..
Комментарии:
1. какой тип отчета вы используете? crystal report или встроенный datareport?
2. @Rasel: просто отчет, который я создаю с нуля
3. Я предполагаю, что вы пытаетесь отобразить отчет (который вы создадите из набора записей) в форме. затем сначала вставьте форму и в этой форме добавьте фрейм. добавьте равное количество меток в фрейм, подобный вашему набору записей. затем выполните цикл по набору записей и в каждом цикле добавляйте каждую строку с заголовком метки из набора записей во время выполнения.
4. Чтобы использовать набор записей в другом месте (форма / ..), добавьте модуль и в модуле объявите набор записей как общедоступный
5. @darkjh. Предложение Rasels находится на правильном пути и является единственным работоспособным при любых условиях простым и непринужденным
Ответ №1:
Вы должны быть в состоянии выполнить это, просто передав правильную инструкцию SQL в свой отчет. Это можно сделать, используя вступительные аргументы.
Предполагая, что вам действительно нужен идентичный набор записей в вашем отчете, который вы видите в своей форме, то, что вам нужно сделать, зависит от того, как вы открыли свою форму или как вы фильтруете свою форму. Вы действительно могли бы использовать идентичный объект набора записей DAO и установить для вашего объекта набора записей отчетов копию или клон объекта набора записей формы. Однако это может быть необязательно для получения результатов, которые вы ищете.
Решение # 1
Если ваша форма использует запрос или инструкцию SQL, вы можете использовать это решение.
Код в вашей форме:
DoCmd.OpenReport "rptReportName", acViewPreview, , , acWindowNormal, Me.RecordSource
Код в вашем отчете:
Private Sub Report_Open(Cancel As Integer)
Me.RecordSource = Nz(Me.OpenArgs, "")
End Sub
Решение # 2
Используйте это решение, если ваша форма использует свойство filter формы для фильтрации до правильного набора записей. Я предполагаю, что затем вы хотите передать это условие фильтрации в отчет. Вам нужно настроить отчет так, чтобы он использовал тот же источник записей, что и ваша форма (или он должен, по крайней мере, содержать таблицу / поля, которые будут включены в вашу инструкцию filter). Проблема в том, что передача recordsource вашего отчета в вашу форму не передает никакого фильтра, который вы могли бы установить в форме.
DoCmd.OpenReport "rptReportName", acViewPreview, , Nz(Me.Filter, ""), acWindowNormal
В качестве последнего замечания, невозможно установить свойство recordset отчета. Вы можете назначить Recordsource, как я уже показывал (recordsource — это имя таблицы, имя запроса или инструкция SQL), но вы не можете использовать свойство Recordset, если база данных не является проектом Access Data, который я вообще не рекомендую использовать.
Правка1
Из исходного сообщения было неясно, какую проблему пытался решить OP. Я неправильно предположил, что у него возникли проблемы с отображением в его отчете тех же записей, что и в его форме. Похоже, что скорее OP обеспокоен выполнением двух поездок на сервер для извлечения записей.
Поскольку вы не можете задать значение набора записей в отчете Access, лучшим вариантом может быть создание локальной таблицы Access и простое использование ее в качестве временной таблицы. Я не знаю, какого размера обычно ваш набор записей. Если он довольно большой (более 5000 записей), это решение может оказаться не очень хорошей идеей. Одна из проблем, о которой я могу подумать, заключается в том, что это приведет к тому, что файл вашего приложения базы данных внешнего интерфейса со временем будет раздуваться, если у вас нет настройки файла для запуска Compact и восстановления при закрытии.
Комментарии:
1. Когда мне это нравится, например, решение 1. Отчет будет открыт с помощью recordsource. Но я думаю, что когда он откроется, он все равно выполнит sql-запрос для получения данных. И эти данные такие же, как в наборе записей моей формы.
2. Если я могу просто передать набор записей из моей формы в мой отчет, это означает отсутствие sql-запроса.
3. darkjh, ты не смог ясно выразиться. Это связано с производительностью? Вы пытаетесь сохранить обращения к серверу? Или речь идет о получении в отчете тех же записей, что и в вашей форме? Вы правы. Оба моих рекомендуемых решения совершат два обращения к серверу для извлечения записей. Если вы читаете мое последнее примечание, ВЫ НЕ МОЖЕТЕ УСТАНОВИТЬ НАБОР ЗАПИСЕЙ В СВОЕМ ОТЧЕТЕ. Это ограничение доступа.
Ответ №2:
Я думаю, что беспокойство по поводу двух обращений к серверу необоснованно.
Если бы вы использовали серверную часть Jet / ACE, Jet кэшировал бы данные локально, и повторного извлечения не было бы, если бы данные не изменились (в этом случае, я думаю, вам, вероятно, понадобились бы актуальные данные, нет?).
При использовании серверной базы данных сам сервер, скорее всего, будет кэшировать результаты, особенно если используемая инструкция SQL идентична в обоих случаях.
Мне кажется, что это случай преждевременной оптимизации.
Ответ №3:
Ну, если я понял из вашего вопроса, вам нужно манипулировать данными в таблице, зная / не зная номер набора записей.
Если это так, то вам нужно изменить представление о том, как обращаться к данным в таблице, потому что продвигать номер набора записей в вашем списке не совсем правильный способ, обычно мы продвигаем данные, а номера записей скрыты.
Поэтому, когда вы читаете свою таблицу, попробуйте передать свои поля в переменные для последующего использования или передать их непосредственно в ваше представление списка.
Способ доступа к таблице для получения всех данных, поступающих из другого процесса, который всегда менялся.
Но даже если вы хотите сохранить номера записей для последующего использования, попробуйте объявить имя как общедоступную переменную, так как ArrayList()
тогда при чтении из таблицы вы можете использовать 'Variable'.add(RecordNumber)
.
Поэтому, когда вам нужно получить доступ к определенному номеру, возьмите номер строки чтения из вашего списка просмотра, позвонив VariableName(ListViewLineNumber)
Пожалуйста, сообщите мне, подходит ли это решение для решения вашей проблемы.
Комментарии:
1. @ Это означает, что я должен создать глобальную переменную (ы) для передачи этих значений?
2. @darkjh. Да, я предлагаю глобальные переменные для этой цели, потому что мы можем захотеть перейти к другому подразделению или функции, чтобы использовать их. Но логично использовать локальные переменные, которые не рекомендуются.
3. Как именно создать отчет Access, используя этот подход? Хотя, конечно, если вы отображаете только одну запись, можно извлечь значения из формы, отображающей эту запись, но если вашему отчету необходимо отобразить более одной записи, это просто не сработает.
4. @David-W-Fenton. Если вы заметили, что отчет представляет собой нечто, созданное самостоятельно. Таким образом, у него есть все возможности использовать инструкции кода для работы и непрерывно считывать данные из таблицы, отображаемые в виде списка. Точно в момент чтения он поместит arraylist, чтобы загрузить в него номер записи. И поверьте мне, это выполнимо
5. Это звучит как огромный объем работы и противоречит преимуществам Access, который касается связанных данных.