MS Access

А почему у меня не работает...

Опубликовано: 30 апр 04
Рейтинг:

Автор: Senin Viktor, Владимир Саныч, участники форума по Аксессу
Прислал: Geo, Владимир Саныч

Вопросы


Почему у меня не работает (вопросы, наиболее подходящие к общей теме FAQ'а):

Q1: Перестали распознаваться служебные слова, такие как Left, Right, Database и т.д.

Q2: Ставлю MsgBox или брейкпойнт - работает. Убираю - не работает.

Q4: Начинается совершенно непонятное поведение mdb.

Q5: Пишу программу на VBA, и при этом все дрожит, недописанная строка красится красным, как содержащая ошибку, курсор сам перескакивает по строке куда вздумается, сами расставляются пробелы и большие буквы и т.д.

Q11: База данных перестала сжиматься (с диагностикой: таблица АБВГДТабле already exists).

Q13: На команды с объектом Recordset выдается ошибка о несоответствии типов или об отсутствии методов у объекта.

Q21: Выскакивает длинное сообщение, в котором в числе прочего имеется следующий текст: The expression may not result in the name of a macro, name of a user-defined function, or [Event Procedure].

Q34: Получаю номер ошибки и не могу узнать, что этот номер обозначает.

Q40: Не исполняется код обработчика события.

Q42: Неправильно работает сравнение дат.

Запросы и селекты:

Q18: Аксесс переворачивает даты, меняет местами день и месяц. Вариант: неверно срабатывают вычисления или проверки, связанные с датами.

Q19: Не работает проверка на равенство/неравенство.

Q24: Команда SQL не видит переменных.

Q25: В перекрестном запросе не удается соблюсти постоянный порядок и количество столбцов.

Q26: Не работает запрос с двумя джойнами:
select * from A left join B on A.A=B.B left join C on A.A=C.C

Q28: У меня есть логическое поле. Хочу выдать записи, в которых оно отмечено. Пишу в запросе:
WHERE [этополе]=1
- и запрос не работает.

Q29: Составляю условие WHERE (или любую другую часть селекта, или селект полностью, и вообще любую команду SQL) как стринг, собирая его/ее из значений переменных, контролов и т.д. Не работает.

Q32: RecordCount возвращает 1, независимо от реального количества записей в рекордсете.

Q33: Execute не возвращает сообщений об ошибке, даже если часть записей ему не удается обновить/добавить/удалить.

Q37: Получаю ошибку при запуске запроса на выборку (select) при помощи команды Execute либо RunSql.

Q38: Не работает условие с оператором Like.

Q39: В таблице нарушена сортировка. Или: Не получается обратиться к предыдущей (первой, последней и т.д.) записи в таблице.

Формы и отчеты:

Q7: Не помогают f.Recalc, f.Refresh, f.Requery, f.Repaint, где f - форма.

Q14: Не работает событие OnOpen подчиненного отчета.

Q16: Плохо работает программа, в которой используется свойство текстбокса или комбобокса Text.

Q20: Не могу настроить комбобокс.

Q22: Обработчик события KeyDown берет старые значения полей.

Q23: Не могу заставить форму всегда открываться в режиме Maximized (вариант: Restored).

Q30: Не могу сделать контролу Visible=False (варианты: Enabled=False, Locked=True). Аксесс говорит, что на этом контроле фокус.

Q31: Не могу сделать контролу Visible=False в табличной форме.

Q36: Обращаюсь к форме через коллекцию Forms и получаю сообщение, что Аксесс не может эту форму найти.

Q40: Не исполняется код обработчика события.

Q41: Не работает сортировка в отчете.

Q43: Отчет в режиме конструктора страшно тормозит.

Модули:

Q1: Перестали распознаваться служебные слова, такие как Left, Right, Database и т.д.

Q2: Ставлю MsgBox или брейкпойнт - работает. Убираю - не работает.

Q3: Вылазит сообщение: Expected variable or procedure, not module.

Q5: Пишу программу на VBA, и при этом все дрожит, недописанная строка красится красным, как содержащая ошибку, курсор сам перескакивает по строке куда вздумается, сами расставляются пробелы и большие буквы и т.д.

Q6: Почему неправильно работает округление?

Q10: Не удается уложиться в синтаксис SQL либо VBA, потому что имя таблицы, поля, формы и т.д. содержит нехорошие символы, типа пробелов или минусов.

Q12: Я написал/а программу, а она не работает.

Q13: На команды с объектом Recordset выдается ошибка о несоответствии типов или об отсутствии методов у объекта.

Q15: Не работает обращение к процедуре, которое я пишу так:
MySub (x, y) - тут выдается ошибка компиляции
MySub (x) - тут почему-то параметр передается по значению, а не по ссылке

Q18: Аксесс переворачивает даты, меняет местами день и месяц. Вариант: неверно срабатывают вычисления или проверки, связанные с датами.

Q19: Не работает проверка на равенство/неравенство.

Q35: Пишу цикл по объектам, входящим в какую-нибудь коллекцию CurrentDb, и получаю сообщение "Object invalid or no longer set".

Прочее:

Q4: Начинается совершенно непонятное поведение mdb.

Q8: В Аксессе 2002 кнопка "Создание MDE файла" не активна.

Q9: Не удается создать файл mde.

Q11: База данных перестала сжиматься (с диагностикой: таблица АБВГДТабле already exists).

Q17: Я так расставил галки в настройках аппликации, что мне теперь самому не добраться до меню Аксесса.

Q21: Выскакивает длинное сообщение, в котором в числе прочего имеется следующий текст: The expression may not result in the name of a macro, name of a user-defined function, or [Event Procedure].

Q27: Не работают параметры командной строки, напр. /excl и т.д.

Q34: Получаю номер ошибки и не могу узнать, что этот номер обозначает.

Вопросы с ответами


Q1: Перестали распознаваться служебные слова, такие как Left, Right, Database и т.д.

A1: Проверь, не слетели ли ссылки. Из окна открытого модуля Tools -> References.

http://www.firststeps.ru/vba/excel/r.php?41

В частности, может слететь следующая ссылка:

Visual Basic for Applications

А вообще, слово MISSING у любой из ссылок может привести к такому эффекту. Надо либо снять птичку у ссылки с MISSING (если эта ссылка не нужна для работы программы), либо перенаправить ее на файл, который действительно существует.

A2: Если в региональных настройках Windows в качестве разделителя списков задана не запятая, а, скажем, точка с запятой, то при обращении к функциям надо ставить между аргументами именно этот разделитель (если обращение находится в запросе, в свойствах контрола и т.п., а не в модуле).

A3: В качестве имени переменной могло случайно оказаться взято служебное слово. Такую переменную желательно переименовать.

Q2: Ставлю MsgBox или брейкпойнт - работает. Убираю - не работает.

A: Поставь DoEvents вместо MsgBox'а или брейкпойнта.

Q3: Вылазит сообщение: Expected variable or procedure, not module.

A: Начиная с Access 95, запрещено давать модулям имена, совпадающие с названиями переменных и процедур, а также со служебными словами. Если при компиляции появилось такое сообщение - значит, среди модулей попался такой, имя которого совпадает с чем-то в той строке, на которую Аксесс кричит. Его надо переименовать.

Q4: Начинается совершенно непонятное поведение mdb.

A: Скорее всего файл испортился. Надо попробовать его починить. Много способов починки можно увидеть, если запустить поиск по форуму на слово JetComp или decompile.

Q5: Пишу программу на VBA, и при этом все дрожит, недописанная строка красится красным, как содержащая ошибку, курсор сам перескакивает по строке куда вздумается, сами расставляются пробелы и большие буквы и т.д.

A: У одной из открытых форм работает таймер.

Q6: Почему неправильно работает округление?

A: Существует много методов округления. Функция Round округляет по своим правилам, которые могут отличаться от нужных. Поэтому лучше округлять явным образом, осознавая, что именно делает программа.

Вот длинный топик, в котором обсуждался этот вопрос: https://www.sql.ru/forum/actualthread.aspx?bid=4&tid=31080&pg=-1

Q7: Не помогают f.Recalc, f.Refresh, f.Requery, f.Repaint, где f - форма.

A: Поможет f.RecordSource = f.RecordSource.

Q8: В Аксессе 2002 кнопка "Создание MDE файла" не активна.

A: Файл mdb создан в формате Аксесса 2000. Его надо преобразовать в формат 2002.

Q9: Не удается создать файл mde.

A1: Возможно, в программе есть ошибки компиляции. Попробуй откомпилировать программу. Из окна модуля Debug -> Compile.

А2: Возможно, файл создан не в той (или не для той) версии Access. Попробуйте преобразовать файл к текущей версии. Имейте в виду, что Access 2002 (XP) по умолчанию создает файлы формата Access 2000. Изменить это можно в меню Сервис -> Параметры -> вкладка "Другие" -> Формат файла по умолчанию.

A3: Возможно, проект содержит ссылки (Из окна модуля Debug -> References...) на файлы .mdb. Создать файл .mde можно, только предварительно преобразовав к .mde файлы, на которые он ссылается.

Q10: Не удается уложиться в синтаксис SQL либо VBA, потому что имя таблицы, поля, формы и т.д. содержит нехорошие символы, типа пробелов или минусов.

A: Заключи это имя в квадратные скобки.

Q11: База данных перестала сжиматься (с диагностикой: таблица АБВГДТабле already exists).

A: Это мягкий вариант порчи базы. Скорее всего ты скопировал базу во время работы пользователей. Лечение - импорт в новую базу.

Q12: Я написал/а программу, а она не работает.

A: Ищи баг. Ставь точки останова, проверяй значения переменных, ну в общем как большой/ая.

Q13: На команды с объектом Recordset выдается ошибка о несоответствии типов или об отсутствии методов у объекта.

A: Пиши не просто Recordset, а DAO.Recordset. А также: DAO.Database и т.д.

Q14: Не работает событие OnOpen подчиненного отчета.

A: Можно все содержимое OnOpen перенести в какое-нибудь событие родительского отчета, например в OnFormat его Header'а.

Q15: Не работает обращение к процедуре, которое я пишу так:
MySub (x, y) - тут выдается ошибка компиляции
MySub (x) - тут почему-то параметр передается по значению, а не по ссылке


A: Правильный синтаксис выглядит так:

Call MySub(x, y)
MySub x, y
a = MyFun(x, y)

Все скобки кроме этих воспринимаются как часть самого параметра.

Q16: Плохо работает программа, в которой используется свойство текстбокса или комбобокса Text.

A: Свойство Text доступно только тогда, когда этот текстбокс или комбобокс находится в фокусе. Чтобы программа работала всегда, надо пользоваться не свойством Text, а:

- у текстбокса - свойством Value (которое является свойством по умолчанию, следовательно можно вообще это слово опустить вместе с предшествующей точкой);
- у комбобокса - свойством Column(номерколонки).

Q17: Я так расставил галки в настройках аппликации, что мне теперь самому не добраться до меню Аксесса.

A: Открой пустой Аксесс, а потом внутри него открой свою аппликацию, придерживая клавишу Shift. Если есть пароль, то держать Shift надо после ввода пароля в момент нажатия на Enter (или кнопку OK).

Q18: Аксесс переворачивает даты, меняет местами день и месяц. Вариант: неверно срабатывают вычисления или проверки, связанные с датами.

A: Возможно, дата была записана в строковой переменной (вариант: использована строковая функция Date$ либо текстбокс, не привязанный к полю типа Date/Time). Строка, содержащая даты, интерпретируется Аксессом на основании нескольких правил, в которые входят синтаксис команд SQL (где нужно писать #MM/DD/YY#) и региональные настройки Windows. Надо знать, где и как это работает, а при возможности избегать записи дат в строках. Во многих случаях помогает функция DateSerial.

Q19: Не работает проверка на равенство/неравенство.

A1: Проверка на равенство допускается только для целочисленных типов данных (в которые входит и тип Currency, который хранится в памяти как целое число сотых). Типы с дробной частью (кроме Currency), такие как Double, Float, хранятся приблизительно, и даже если визуально два числа кажутся равными, их внутреннее представление может отличаться. Для таких чисел надо проверять не A=B, а Abs(A-B)<eps, где eps - какое-нибудь достаточно малое число. Внимание: важно, какого типа данные, а не как задан формат для их отображения в таблице или форме.

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

A2: Если одно из значений в выражении Null, то любая комбинация арифметических и логических операций с ним вернет Null (который приравнивается к False). Чтобы этого избежать, можно пользоваться функцией IsNull, которая в соответствующем случае возвращает True.

Примечание 1. Операция & работает иначе.

Null + "zzz" (или наоборот) -> дает Null
Null & "zzz" (или наоборот) -> дает "zzz"

На этом основан следующий трюк:

(A + ",") & (B + ",") & (C + ",")

Если какое-то из значений A, B, C равно Null, то вся соответствующая скобка даст Null и соответствующая запятая будет уничтожена, а затем соединение через & возьмет только те слагаемые, где не Null.

Примечание 2. В некоторых случаях иначе работают также операции Or и And. А именно:

Null Or True (или наоборот) -> дает True
Null And False (или наоборот) -> дает False

Q20: Не могу настроить комбобокс.

A: Вот простейший случай:

RowSourceType = Table/Query
RowSource = select a, b from t
    - где сначала названо поле с кодом (которое будет заноситься в таблицу),
    а потом поле с текстом (которое будет показываться)
BoundColumn = 1
LimitToList = Yes
ColumnCount = 2
ColumnWidths = 0;3
    - главное, чтобы у первой колонки ширина была 0


А не через таблицу - отличия следующие:

RowSourceType = Value List
RowSource = 1;"one";2;"two";3;"three"


Q21: Выскакивает длинное сообщение, в котором в числе прочего имеется следующий текст: The expression may not result in the name of a macro, name of a user-defined function, or [Event Procedure].

A1: Возможно, Аксессу не нравится то, что написано в одном из свойств, описывающих события.

A2: Возможно, отлетела какая-нибудь ссылка.

A3: Возможно, один из контролов или одна из секций формы содержит в своем имени символы национального алфавита, которые не поддерживаются текущей версией Аксесса или Windows.

Q22: Обработчик события KeyDown берет старые значения полей.

A: Вместо KeyDown используй KeyUp.

Q23: Не могу заставить форму всегда открываться в режиме Maximized (вариант: Restored).

A: Для Restored можно задать свойство PopUp=True. Для Maximized сложнее:

Private Sub Form_Activate()
DoCmd.Maximize
End Sub
Private Sub Form_Deactivate()
DoCmd.Restore
End Sub


Q24: Команда SQL не видит переменных.

A1: Зато видит функции. Можно сделать функцию, которая будет возвращать значение переменной. Эта функция обязана быть описана в обычном модуле как Public.

A2: Можно формировать команду SQL программно и вставлять туда значения переменных как константы. Подробнее: https://www.sql.ru/faq/faq_topic.aspx?fid=157

Q25: В перекрестном запросе не удается соблюсти постоянный порядок и количество столбцов.

A: Добавь в конец селекта запроса (т.е. всей строки запроса, а не ее части SELECT) следующее: in ("two","three","one"), где в скобках перечислены столбцы в нужном порядке.

Q26: Не работает запрос с двумя джойнами:
select * from A left join B on A.A=B.B left join C on A.A=C.C


A: В Аксессе надо в таких запросах ставить скобки:
select * from ((((A left join B on A.A=B.B) left join C on A.A=C.C) left join D on A.A=D.D) left join E on A.A=E.E) left join F on A.A=F.F

Q27: Не работают параметры командной строки, напр. /excl и т.д.

A: Командная строка должна начинаться с ...msaccess.exe, и только потом название файла и все параметры. Без msaccess.exe эти параметры никому не нужны.

Q28: У меня есть логическое поле. Хочу выдать записи, в которых оно отмечено. Пишу в запросе:
WHERE [этополе]=1
- и запрос не работает.


A: Логическое True в Аксессе (в отличие от SQL-сервера) - это не 1, а -1. (Кстати, если просто написать WHERE [этополе], то тоже будет работать, причем если поле не логическое, то будут выданы все записи, где значение этого поля не 0.)

Q29: Составляю условие WHERE (или любую другую часть селекта, или селект полностью, и вообще любую команду SQL) как стринг, собирая его/ее из значений переменных, контролов и т.д. Не работает.

A: Первым делом остановись в дебаггере и посмотри на полученный стринг. Если и после этого не станет ясно, что не так, то попробуй запустить его как сохраненный запрос. Подробнее о правилах включения переменных в строку запроса см.: https://www.sql.ru/faq/faq_topic.aspx?fid=157

Q30: Не могу сделать контролу Visible=False (варианты: Enabled=False, Locked=True). Аксесс говорит, что на этом контроле фокус.

A: Значит надо сначала перевести фокус на другой контрол:

c.SetFocus

Если нет контрола, который заведомо в любой ситуации сможет принять фокус, то его можно создать: либо CommandButton со свойством Transparent=True, либо OptionGroup со свойством BorderStyle=Transparent. Юзер его не заметит.

Q31: Не могу сделать контролу Visible=False в табличной форме.

A: В табличной форме надо делать ColumnHidden=True.

Q32: RecordCount возвращает 1, независимо от реального количества записей в рекордсете.

A: Дойди до последней записи, например при помощи метода MoveLast. Если надо, вернись обратно. Тогда RecordCount вернет правильное количество.

Q33: Execute не возвращает сообщений об ошибке, даже если часть записей ему не удается обновить/добавить/удалить.

A: Пользуйся полным синтаксисом: Execute ..., dbFailOnError.

Q34: Получаю номер ошибки и не могу узнать, что этот номер обозначает.

A: Функция AccessError, вызванная с этим номером в качестве параметра, даст ответ на этот вопрос.

Q35: Пишу цикл по объектам, входящим в какую-нибудь коллекцию CurrentDb, и получаю сообщение "Object invalid or no longer set".

A: Проблема в CurrentDb. Надо либо занести его в переменную (и далее пользоваться ею), либо воспользоваться конструкцией With CurrentDb ... End With.

Q36: Обращаюсь к форме через коллекцию Forms и получаю сообщение, что Аксесс не может эту форму найти.

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

Q37: Получаю ошибку при запуске запроса на выборку (select) при помощи команды Execute либо RunSql.

A: Эти команды предназначены только для запуска исполняемых запросов (добавление, обновление, удаление и т.д.). Запрос на выборку нельзя запустить. Им можно пользоваться только (приблизительно) как таблицей: открыть его на экране, открыть на нем рекордсет, посадить на него форму и т.д.

Q38: Не работает условие с оператором Like.

A: Если ты работаешь с ADO при включенном режиме совместимости с синтаксисом SQL-сервера (или просто с SQL-сервером), то во втором операнде оператора Like надо вместо * использовать %, а вместо ? - _.

Q39: В таблице нарушена сортировка. Или: Не получается обратиться к предыдущей (первой, последней и т.д.) записи в таблице.

A: В таблице нет сортировки и нет понятия предыдущая (и т.д.) запись. Сортировка и предыдущая (и т.д.) запись будет в запросе с заданным ORDER BY.

Q40: Не исполняется код обработчика события.

A: Первым делом проверь, написано ли [Event Procedure] в окне свойств в строке соответствующего события.

Q41: Не работает сортировка в отчете.

A: Отчет, в отличие от формы, не наследует сортировку от запроса, на котором он основан. В отчете надо задавать сортировку заново через окошко Sorting And Grouping.

Q42: Неправильно работает сравнение дат.

A1: Возможно, эти даты с точки зрения Аксесса являются стрингами. В этом случае он их сравнивает как стринги, т.е. смотрит, что идет раньше по алфавиту. Например, с при сравнении строк будет верно выражение: "31.01.2000">"01.02.2000".

A2: Еще одна возможная проблема при сравнении дат разобрана в ответе на вопрос Q19.

Q43: Отчет в режиме конструктора страшно тормозит.

A: Попробуй перевести принтер по умолчанию на другой принтер.

Комментарии




Необходимо войти на сайт, чтобы оставлять комментарии

Раздел FAQ: MS Access / А почему у меня не работает...