LEADERSOFT.ru Разработка на заказ программ и сайтов
ЕСЛИ БАЗА ВАМ НУЖНА В ЛИДЕРСОФТ ЗАЙДИ СПЕРВА!
Список всех статей ... Подписка на новости (рассылка через subscribe.ru)




































Выпуск 18. Ответы на вопросы

Подписка: "Access 2000 - программирование и готовые решения"
Дата:         15.11.2000
Сайт:         http://www.leadersoft.ru
Слоган:     Если база Вам нужна, в LeaderSoft зайди сперва.
Комментарий: 
      Мы разрабатываем по заказам клиентов различные программы, используя Microsoft Access. Базы данных разрабатываются "с нуля" или, используя готовые решения (Склад, Касса, Банк и т.п.), что позволяет достаточно гибко решать финансовые вопросы по оплате услуг за разработку. Для регистрации заказа заполните форму: Регистрация заказа на разработку

Введение.
    
В данном выпуске даются ответы на 21 вопрос по предыдущей рассылке. Вот ссылка на вопросы, которые остались без ответа: http://www.leadersoft.ru/subscribe/questions.htm. Обязательно проверьте наличие ваших вопросов на этой странице. Если его нет, или Вы решили изменить текст вопроса, то сообщите об этом по email:
.
    Вы можете попробовать сами решить некоторые проблемы или добавить свои комментарии к уже решенным вопросам.
    Спасибо всем разработчикам Access программ, которые дали ответы на приведенные ниже вопросы.

Вопрос 5. Как сделать, чтоб в отчете сумму прописью выдавало ?
   Ответ. Вставьте в поле отчет. В свойство данные вставьте: =funRusMoney([Сумма]). Саму функцию возьмите из модуля la_form1.mdb. Если желаете понять как связаны в коммерческих программах таблицы, запросы и сумма прописью, то смотрите модуль: B001.mdb или A012.mdb в Магазине "Лидер Access".
Вопрос 6. Кто-нибудь задавался целью, чтобы отчет в виде книжки можно было распечатать?
   Ответ. Если мне это нужно, я всегда отчеты экспортирую в Word 2000. По сравнению с Word 97 там появились специальные возможности для печати брошюр. Проверял неоднократно при печати инструкций, качество отличное. Для этого сделайте маленькую пустую книжку из бумаги размером, например, 2см x 4см. Пронумеруйте ее и при печати через Word используйте нумерацию для ввода страниц. Пример печати для брошюры из 16 страниц на листах формата A4: 1 блок: 16,1, 14,3, 12,5, 10,7. Переверните листы и напечатайте: 8,9, 6,11, 4,13, 2,15. Теперь можно сложить страницы. Не забудьте в разделе "Параметры страницы" установить флажок "2 страницы на листе".
Вопрос 7. Мне приходится часто работать с данными из DBF файлов. Иногда они содержат достаточно много данных и выборка без ключа занимает много времени. Все эти данные я беру из CLIPPERовской базы. Там есть индексные файлы, но их формат не поддерживается ODBC. Можно ли как-то решить такую проблему? Сейчас я или смиряюсь, или импортирую каждый раз в ACCESSовские таблицы. Как вообще обрабатывать внешние индексы - натолкнулся на INF файлы, но нигде не нашел описания правильной работы с ними.
   Denis Katkovsky: Dionisio@Mail.RU Пользоваться внешними не рекомендуется, так как Акцесс некорректно их использует. К тому же в Clipper'е, например, можно определить свои драйверы работы с БД и полностью контролировать построение индексов. Так что их, естественно, не поймет ни одна другая программа. Так что выход из ситуации действительно один - импортировать базу в МДБ. Не обязательно в основную - можно создать временную, а затем удалить. ...ну или смириться с тормозами.
   Виктор Конюков. Ваш вопрос - "больной" для многих. Можно предположить, что если нет достаточных примеров работы с внешними индексами, то с ними не пытаются "серьезно" работать через Access. Некоторые рассуждения на эту тему я привел в подписке 17 (16 вопрос).
Вопрос 8. Последние 5 лет я занимаюсь тем, что создал и постоянно дорабатываю по мере необходимости базу для фирмы занимающейся ЖД перевозками (обработка данных из т/т накладных, расчет оплаты, выставление счетов и т.д.). В последнее время моя сетевая база работает в Access97. При попытке пробного перевода ее в Access2000, я столкнулся с проблемой: функция Like отказывается производить поиск по маске если в ней содержатся символы кириллицы "Е", "К", "Г". В Access97 все работает.
  Виктор Конюков. Вообще очень странно, что у Вас Like не работает с этими символами. Посмотрите в файле la_form.mdb контекстный поиск. Все работает. Возможно у Вас очень сложный SQL запрос и требуется его упрощение.
  Igor V. Makeev igor@mebelmassiv.tula.ru Кстати, есть такой баг в A2k, сам не встречал, т.к. пока практически ничего не пишу на 2000, но вот выдержка из FAQ RU.MSACCESS
===
28) Q: (A2000only!) Можно ли боpоться с непpавильной pаботой пpи использовании pyсских бyкв в опеpатоpе LIKE в yсловиях запpоса/фильтpа? A: Фокyс в том, что если таблицы хpанить в базе данных 97-го фоpмата, то A2000 pаботает с ними ноpмально. Так что достаточно конвеpтнyть табличнyю базy в фоpмат A97. (Andrey Fedorov 5055/34)
===
  Виктор Конюков. Ну здесь я полностью не согласен с Вами. Like не хранится в mdb файлах, поэтому, если оператор Like возвращает неправильный результат, то это будет для любых присоединенных таблиц access, dbase, foxpro, paradox и т.п.
Вопрос 12. 1. Я интересовался у Вас размерами форм на мониторах с разным разрешением. Как определить разрешение экрана и текущие координаты и размеры форм я понял. Но что с этим делать дальше? Неужели необходимо пересчитать координаты и размеры всех элементов формы? К примеру, при разрешении 600*800 кнопка "Выход" находится в правом нижнем углу, а при 480*640 вылазит за пределы экрана. Если пересчитать только её координаты, то она залезет на другой объект.
  Ответ. Если Вы собираетесь масштабировать форму, то Вам нужно изменить не только ее, но и шрифт символов на кнопках, метках и т.п. Задача это не очень простая и требует высокой квалификации. С другой стороны, зачем Вам это нужно. Мне не встречался заказчик по Access, для которого это имело бы принципиальное значение. Оптимальный размер формы для бизнес-программ: 480*680. Большинство бухгалтеров работают на мониторах в 15" и не любят мелкие элементы в программах, так что очень усиленно стараться переводить программу на разрешение 600*800 не стоит.
Вопрос 13. 2. Как с помощью VBA создать таблицу с полем счетчика?
Denis Katkovsky: Dionisio@Mail.RU Например, выполнить такой запрос: "CREATE TABLE SimpleTable (PersonID counter NOT NULL  , FirstName varchar(50) NOT NULL, LastName varchar(50) NOT NULL, CONSTRAINT PrimaryKey PRIMARY KEY (PersonID));" 
Виктор Конюков. Одно из решений Вы найдете в файле la_table.mdb
Igor V. Makeev igor@mebelmassiv.tula.ru
В А2k можно еще вот так:
Dim c As ADODB.Command
Set c = New ADODB.Command
c.CommandText = "CREATE TABLE tblCodeCounterDataTypes (Field1_IDENTITY IDENTITY(10,5), Field2 TEXT(10))"
c.ActiveConnection = CurrentProject.Connection
c.Execute
Set c = Nothing
Вопрос 14. Access как правило предлагает создать автоматически - в виде поля типа "Счетчик". Со временем в этом поле оказываются значения самые разные. Каким образом можно обновить это поле (вариант - внести запись с заданным значением в поле "Счетчик") ?
  Виктор Конюков. Решается это через SQL запрос или с использованием объекта Recordset и его функции AddNew. В поле счетчика должен содержаться уникальный номер записи, иначе будет сгенерирована ошибка. С другой стороны, Вы можете перевести счетчик из режима последовательных номеров в случайные. К сожалению обратно это сделать не удастся.
  Alexander Brezak: balex@galnaftogas.com  Если уж и городить огород, то зачем мучать поле "счетчик". Создаешь свое поле и программно генерируешь нужные значения. А поле счетчика позволяет "забыть" про генерацию уникальных ID, т.е. тут за вас все делает Access.
Вопрос 16. Как можно программным способом прочитать все поля (в т.ч. и списки) одной формы и данные внести в другую?
   Ответ. В лекциях (6с) я рассказал как создать элементы формы. Эту программу можно переделать для ввода элементов не из запроса, а из формы. Думаю, что это не сложно.
Вопрос 17. При выводе на принтер отчета из Access ([Файл] -> Печать) появляется диалог "Печать", где в соответствующих окошках можно выбрать диапазон страниц для печати с ... по ... Проблема состоит в том, что на разных компьютерах максимальное количество цифр, которое можно ввести в эти окошки колеблется от трех до пяти. На компьютере с Win95 можно ввести пятизначное число (max 99999), с WinNT 4.0 на одной машине три цифры, на другой четыре, под Win 2000 на каждой из двух проверенных машин по четыре цифры. Получается, что страницу с номером > 100000 вообще нельзя вывести на печать, а на некоторых машинах страницу > 1000. От чего это зависит? Полная переустановка офиса не меняет ситуации. Модель и драйвер принтера, структура отчета не влияют на это ограничение (были проверены 5 разных принтеров с различными драйверами). Конфигурации компьютера (размер памяти и ЖД) тоже не влияет на это.
   Ответ. Вопрос к Вам. А зачем это нужно? Вы не задумывались сколько времени Access будет форматировать отчет с числом страниц, например, более 500. У большинства пользователей терпения на это не хватит. Лучше подумайте как улучшить запрос отчета или попробуйте использовать для печати фильтр отчета (см. la_report.mdb).
Вопрос 18. Подскажите пожалуйста, как в Access-2000 управлять шириной и высотой окна? Насколько я понимаю ширина формы (me.width) и ширина окна - разные вещи? Хотел бы менять размеры окон и элементов в зависимости от разного разрешения экрана, но что-то не выходит. При убавлении me.with она действительно убавляется (я это контролирую по ее значению, выводя на экран) , а ширина окна так прежней и остается.
  Виктор Конюков. Пример использования API функций для Вашего случая дан в программе la_form.mdb смотрите пример N4.
Igor V. Makeev igor@mebelmassiv.tula.ru
   Для изменения размеров API не нужно - DoCmd.MoveSize
Вопрос 19. У меня есть проблема... Руководству по зарез необходимо иметь график на котором в положительной (сверху) части отражаются средства фирмы, в отрицательной части (внизу с минусом) отражаются задолженности, и где то скачущую из плюса в минус и обратно сальдирующую линию. Проблема в сальдирующей линии. Она должна быть в положительной части синей, а в отрицательной - красной. Есть ли у Вас мысли как можно это реализовать (хотя бы в Excel).
   Ответ. В Excel нет. Для Access пример использования разноцветных линий в отчете дан в файле: la_report.mdb пример номер 6.
Вопрос 20. Добрый день! Работает следующая конфигурация: центральный склад (Access 97, Windows NT 4 (workstation)) - 2 компьютера. Розничная продажа: Access 97, Windows 98 - 2 компьютера. Данные находятся в двух файлах MDB на компьютере склада. Все 4 MDE файла (два складских и два розничных) завязаны на таблицы обоих MDB файлов. Потоки данных большие, работает система 3 месяца и в 2-х таблицах склада уже по 15000 записей. Один раз столкнулись с проблемой ошибки в одной конкретной таблице в MDB файле розницы. Но основная проблема следующая: 1-2 раза в неделю при обращении к файлу MDB склада возникает ошибка "Нераспознаваемый формат базы данных". Лечится командой "Восстановить" из меню Access. Формализовать ситуацию не удалось (конкретные обстоятельства появления ошибки не установлены). ЛВС по TCP/IP. Архитектура "Звезда". Центральный сервер сети: Win 2000. Все базы лежат на локальных дисках. Если вы сталкивались с такой проблемой, пожалуйста, помогите добрым советом.
Alexander Brezak: balex@galnaftogas.com 
Может мой ответ кому-то поможет. Встречался я с похожей ситуацией. Правда, у меня был один файл mdb,  в котором размещались таблицы + формы, отчеты, модули и т. д. Когда файл
немного подрос (до 10 М), а обращения к файлу тоже частые, при открытии файла стала часто появляться ошибка "Нераспознаваемый формат базы данных". Я просто разрезал файл на два: в одном остались только таблицы, в другом - все остальное. Покамест, если такая ошибка появляется, то она затрагивает только 2-й файл (с формами, отчетами и т.д.). В принципе, файл с таблицами можно еще больше подробить, а в других файлах сделать просто линки на эти таблицы. Такой подход мне пока помог.
Виктор Конюков. 1. Если у Вас установлен Windows 98, то его надо срочно заменить на Windows 98SE, т.к. в предыдущей версии есть ошибки в сетевом протоколе, смотрите информацию в разделе сайта "Аварийка". 2. Попробуйте сжать базу данных с помощью импорта объектов (смотрите раздел Аварийка). 3. В разделе "Панель управления" -> "Система" -> "Быстродействие" -> "Графика ..." отключите аппаратное ускорение. 4. Внимание! Неточная информация. При связи через HAB желательно иметь Windows одного класса NT или 98 из разницы в протоколе NetBios.
Вопрос 29. Здравствуйте, после всех полученных мною рассылок и у меня созрел такой вопрос, очень бы хотелось, чтобы в то время, когда идет расчет отчета, то показывался бы индикатор загрузки, ну я так считаю, что с отчетом его связать сложно, ведь когда открывается отчет, то все формы становятся невидимыми, и как Dialog тоже не откроешь. Как тогда быть? Или хотя бы как это сделать в форме и сопоставить с Recordset, желательно на примере.
Denis Katkovsky: Dionisio@Mail.RU
Не в форме, но в строке статуса:
Sub Example()
Dim Counter As Long
'Инициализируем прогрессбар
SysCmd acSysCmdInitMeter, "Вычисляю", 10
For Counter = 1 To 10
'Обновляем прогрессбар
SysCmd acSysCmdUpdateMeter, Counter
'Здесь разместите свой код
Stop 'Это, разумеется, нужно убрать
Next Counter
'Уничтожаем прогрессбар
SysCmd acSysCmdRemoveMeter
End Sub
Виктор Конюков. Вообще поставленный вопрос для тех, кто работает с большими отчетами очень важна. Я это почувствовал на программе "Зарплата и Кадры" при формировании "листочков на зарплату" для нескольких сот сотрудников. Некоторую подсказку по проблеме Вы найдете в файле: la_report1.mdb при работе с фильтром отчета. Форма при масштабировании отчета находится сверху листа страницы. Необходимо только туда вставить свой timer. Пример, как это реализовать на практике, я приведу позже.
Вопрос 32. Как сделать так, чтобы в таблице выделялись не все даты, а только те, которые отвечают специально заданному условию. Например. синим: Date()<= значение <= Date()+2 красным: значение < Date()
Alexander Brezak: balex@galnaftogas.com 
Сам давно пытался сделать что-то подобное в ACCESS 97, и именно в режиме таблицы. К сожалению, я ничего не придумал. В режиме ленточной формы или простой формы цвет легко меняется, а в режиме таблицы ничего не выходит. Но я знаю, я что ACCESS 2000 появилась возможность условного форматирования в _таблице_ (меню Формат->Условное форматирование). Вроде бы очень полезная штука получается.
Виктор Конюков. Маленькое уточнение. Условное форматирование действует только на формы в любом виде (в том числе и в виде таблицы), а в конструкторе таблиц как указано в примере файла la_table.mdb сделать это не удастся.
Вопрос 35. Скажите, можно ли импортировать данные из базы данных CLARION (*.dat). Если можно, то как это сделать?
Автор ответа: chernovd@comset.net  
Возможно...
Существует по крайне мере два варианта: 1. Использовать ODBC драйвер. Правда тут возникает другой вопрос: а где его взять? 2. Непосредственно формат баз данных CLARION (вроде бы) поддерживал Access 2.0. Сам я данной возможностью не пользовался, однако в HELP была статья - как подключить БД CLARION. Там не все было просто - но по описанию подключение было возможно. Так что если остался где нибудь в архивах Access 2.0 поэксперементируйте. Если удастся подключить - далее все просто. Конвертируем в Access 2, после чего конвертируем в более позднюю версию Access.
Виктор Конюков. Попробуйте поискать ODBC драйвер в Интернете. Иногда его можно найти не только у разработчика, но и партнеров, тех кто продает CLARION. Если найдете сообщите подписчикам по Access. Я думаю, что это будет интересно многим.
Алексей. ash@inteh.spb.ru
Вообще, формат файлов данных Clarion (*.dat) известен и достаточно прост. Поэтому, в крайнем случае можно его легко "раскрутить" (правда, если он не запаролен). Единственная проблема, насколько я помню, преобразование дат (в Clarion дата представляется в виде Long (4 байта) со своей точкой отсчета).
Вопрос 36. Я работаю в Access 97. При реплицировании БД в таблицах автоматически создаются новые поля. После импортирования таблиц из реплицированной базы в обычную в новой БД в таблицах визуально этих полей не видно, но фактически они просматриваются в окне отладки при выполнении моего модуля. На программном уровне пытаюсь их удалить с помощью применения метода Delete объекта TableDef, но выводится ошибка: "3280 - Can't delete the field that is part of an index or is needed by the system". Как удалить данные поля?
  Denis Katkovsky: Dionisio@Mail.RU
1. Проверить, не участвуют ли эти поля в индексных выражениях: Таблицы - Конструктор - Индексы 2. Не участвуют ли эти поля в отношениях между таблицами: Сервис-"Схема данных..."
   Виктор Конюков. Если при решении этой проблемы Вы "добрались" до удаления полей программным способом, подумайте над моим предложением: "Может быть лучше Вам написать программу, которая будет импортировать не всю таблицу, а только ее структуру без полей репликации". Далее останется написать запрос на добавление записей. В этом случае не придется сжимать новую базу данных, да и ее структура будет лучше.
Вопрос 38. Просьба помогите решить проблему. Есть в форме несколько списков. При выборе в первом должен формироваться второй, условие значение из первого. Однако во втором списке появляется одно значение(хотя должно быть несколько значений)
Private Sub Список8_AfterUpdate()
Dim rst As Recordset ' ***
Set rst = CurrentDb.OpenRecordset("SELECT * FROM [littel dog] WHERE [idbreed]=" & Me.Список8.Value)
If rst.RecordCount <> 0 Then
With rst
Me.Список10.RowSource = rst!POMET
End With
Else
MsgBox ("Пусто")
End If
rst.Close
End Sub
Автор ответа: chernovd@comset.net 
Попробуйте следующее:
Private Sub Список8_AfterUpdate()
If IsNull(Me.Список8.Value) then
   Me.Список10.RowSource = "SELECT * FROM [littel dog]"
else
   Me.Список10.RowSource = "SELECT * FROM [littel dog] WHERE [idbreed]=" & Me.Список8.Value
end if
Me.Список10.Requery 'Важно
End Sub
Если я правильно помню (сейчас под рукой нет Access) свойство RowSource списка или поля со списком содержит запрос или SQL оператор. Кроме того, если в поле [idbreed] числовое, то все нормально. Если же оно строкового типа то SQL выражение должно выглядеть следующим образом:"SELECT * FROM [littel dog] WHERE [idbreed]='" & Me.Список8.Value &"'"
Вопрос 40. Я очень надеюсь, что Вы сможете ответить на интересующий меня вопрос. А состоит он в следующем: во время написания программы, которая генерирует запросы, мне очень не хочется привязывать параметр запроса к определенной форме, но к сожалению при дальнейшем использовании, т.е. при открытии формы, использующей этот запрос, мне не удается установить значение параметра программным путем, т.к. выводится диалог на задание параметра, и никакие установки параметров запроса в семействе Parameters не помогают. Интересна прежде всего идея, если это вообще возможно, так как во-первых во встроенной справке я ничего толкового не нашел, во-вторых, отсутствие Office 2000.
Автор ответа: chernovd@comset.net
Под термином параметр запроса как я полагаю понимается условие отбора. Если это не так, то ответ не на вопрос. Попробуйте убрать условия отбора в запросе. А при вызове формы программным путем указывай требуемые условия отбора:
DoCmd.OpenForm Имя_Формы, , , Условие
Где условие это выражение WHERE оператора SQL. Также возможно изменение условий отбора в уже открытой форме путем применения команды DoCmd.ApplyFilter или задания свойства Filter (если не ошибаюсь в названии) формы
Igor V. Makeev igor@mebelmassiv.tula.ru
Как уже правильно посоветовали: не строить формы на таких запросах. Т.е.
либо использовать аргументы OpenForm, либо передавать нужные параметры через
вызовы функций, т.е.:
... where Field = GetFieldParam() ...
Вопрос 47. Я разрабатываю базу, чем-то похожую на microsoft'совский Борей. Но заказчику необходима функция проверки времени и, если она соответствует некоторому условию (интервалу с 10:00 до 12:00), то будет выполняться некоторая подпрограмма. Конечно, я понимаю, что это мало относится к созданию баз данных, но всё же надеюсь, что Вы мне подскажите, как это можно сделать и написать.
   Ответ. Для определения времени в Access существует функции Date() и Time(). Вот, например, как можно реализовать действие этих функций. При открытии формы после 10 часов утра появится сообщение об установленных в Windows Дате и Времени.
Private Sub Form_Open(Cancel As Integer)
   If (Time() >= TimeValue("10:00:00")) and (Time() < TimeValue("12:00:00") Then
       MsgBox "Дата: " & Date & ", Время: " & Time()
   End If
End Sub
Вопрос 57 (14.11.2000) При попытке импорта данных (или при связи таблиц ) из файлов DBF , DB (не могу точно сказать чьи это базы - Paradox , FoxPro или еще что-то) все выполняется, кроме одного - вместо русских букв - неизвестно что (даже не "нормальные" кракозябы) . Как решить эту проблему.  ?
   Ответ. Для борьбы с "кракозябами" надо подправить немного реестр Windows. Пример дан для Windows 98.
[HKEY_LOCAL_MACHINE\Software\Microsoft\Jet\4.0\Engines\Xbase]
"DataCodePage"="OEM"
При работе с другими dbf файлами надо изменить OEM страницу на ANSI
"DataCodePage"="ANSI"
P.S. При изменении реестра программным способом изменения вступают после перезагрузки Access.
Вопрос 58 (14.11.2000). Подскажите, пожалуйста, возможно ли решение следующей задачи? Имеются два запроса: в первом только поле даты, во втором - поле комментария. Между собой они никак не связаны. Как создать запрос, в котором эти два поля были бы объединены, т.е. дата1 примечание1, дата2 примечание2, поля даты и примечаний уже отсортированы в соответствующих запросах как надо. У меня получается: дата1 примечание1, дата1 примечание2, дата2 примечание1, дата2 примечание2
     Ответ. В этом примере используется простой запрос на объединение с сортировкой по полю Дата. SELECT * FROM Таблица1 UNION SELECT * FROM Таблица2 ORDER BY Дата;
P.S. Вместо таблиц можно использовать и запросы.
К вопросу о рисовании линий в форме.
Николай Малютин, г. Якутск: malnik@mail.ru
Дополнение к Вашим примерам В примере о рисовании в форме Вы используете способ получения hwnd. Это можно сделать более коротким кодом:
Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWndParent As Long, ByVal hWndChildAfter As Long, _
ByVal lpClassname As String, ByVal lpWindowName As String) As Long
lnghWnd = FindWindowEx(Me.hWnd, FindWindowEx(Me.hWnd, 0, "OFormSub", ""), "OFormSub", "")
Форма Me имеет два дочерних окна класса OFormSub при этом одно из окон имеет дочернее окно класса OFEDT, которое мы и определяем