Не удается добавить запись в форму, я получаю сообщение об ошибке «вы не можете перейти к указанной записи». (MS Access 2007-2016)

#sql #ms-access

#sql #ms-access

Вопрос:

Я очень новичок в MS Access и пытаюсь добавить запись в форму, где всякий раз, когда я нажимаю на кнопку «Добавить запись», я продолжаю получать сообщение об ошибке «Невозможно перейти к указанной записи», что не позволяет мне использовать кнопку. Форма была создана с помощью запроса, который связывает четыре таблицы вместе. Я слышал, что мне нужно сделать запрос доступным для редактирования, но я не уверен, как я это сделаю. (Так выглядит SQL запроса — автоматически генерируется MS Access).

 SELECT tblCustomers.Forename, tblCustomers.Surname, tblCustomers.Telephone, tblCustomers.[Customer ID], Count(tblTickets.[Ticket Number]) AS [CountOfTicket Number], 
tblTickets.[Ticket Type ID], Sum(tblTickets.[Ticket Cost]) AS [SumOfTicket Cost], 
tblCustomerTypes.[Customer Type ID], tblCustomerTypes.[Customer Type], tblTicketTypes.[Ticket Type ID], tblTickets.[Ticket Cost], tblTickets.[Ticket Number] 
FROM ((tblCustomerTypes INNER JOIN tblCustomers ON tblCustomerTypes.[Customer Type ID] = tblCustomers.[Customer Type ID]) 
INNER JOIN tblTickets ON tblCustomers.[Customer ID] = tblTickets.[Customer ID]) INNER JOIN tblTicketTypes ON tblTickets.[Ticket Type ID] = tblTicketTypes.[Ticket Type ID] 
GROUP BY tblCustomers.Forename, tblCustomers.Surname, tblCustomers.Telephone, tblCustomers.[Customer ID], tblTickets.[Ticket Type ID], 
tblCustomerTypes.[Customer Type ID], tblCustomerTypes.[Customer Type], tblTicketTypes.[Ticket Type ID], tblTickets.[Ticket Cost], tblTickets.[Ticket Number];
 

Именно здесь возникает проблема всякий раз, когда я пытаюсь добавить новые записи:

введите описание изображения здесь

На рисунке выше представлена диаграмма взаимосвязей между четырьмя таблицами, а также набор данных под ней.

Приведенные ниже данные относятся к каждой соответствующей таблице:

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

Это запрос, который объединяет четыре таблицы: введите описание изображения здесь

Комментарии:

1. Обычно форма используется для ввода / редактирования данных для одной таблицы. Попробуйте привязать форму к таблице вместо запроса. ГРУППА ПО запросу не может быть отредактирована в любом случае, и это означает, что невозможно создать новую запись.

2. Почему вы хотите отредактировать сводный запрос, который представляет собой сводку данных? Обычно вам нужно отредактировать данные на уровне единиц перед их суммированием.

Ответ №1:

Чтобы форма разрешала добавления (т. Е. Добавление новой записи), Форма должна быть редактируемым источником записи. Однако источником записи вашего запроса является агрегированный запрос, в котором вы выполняете агрегированные функции ( COUNT , SUM ) по группам (см. GROUP BY Пункт). Поскольку совокупные запросы зависят от базовых данных для предоставления результатов, вы не можете обновить эти базовые данные в самом совокупном выводе. Следовательно, формы / отчеты, основанные на совокупных запросах, недоступны для редактирования.

 SELECT tblCustomers.Forename
     , tblCustomers.Surname
     , tblCustomers.Telephone
     , tblCustomers.[Customer ID]
     , tblTickets.[Ticket Type ID]
     , tblCustomerTypes.[Customer Type ID]
     , tblCustomerTypes.[Customer Type]
     , tblTicketTypes.[Ticket Type ID]
     , tblTickets.[Ticket Cost]
     , tblTickets.[Ticket Number] 

     , COUNT(tblTickets.[Ticket Number]) AS [CountOfTicket Number]
     , SUM(tblTickets.[Ticket Cost]) AS [SumOfTicket Cost]

FROM ((tblCustomerTypes
INNER JOIN tblCustomers 
   ON tblCustomerTypes.[Customer Type ID] = tblCustomers.[Customer Type ID]) 
INNER JOIN tblTickets 
   ON tblCustomers.[Customer ID] = tblTickets.[c]) 
INNER JOIN tblTicketTypes 
   ON tblTickets.[Ticket Type ID] = tblTicketTypes.[Ticket Type ID] 

GROUP BY tblCustomers.Forename
       , tblCustomers.Surname
       , tblCustomers.Telephone
       , tblCustomers.[Customer ID]
       , tblTickets.[Ticket Type ID]
       , tblCustomerTypes.[Customer Type ID]
       , tblCustomerTypes.[Customer Type]
       , tblTicketTypes.[Ticket Type ID]
       , tblTickets.[Ticket Cost]
       , tblTickets.[Ticket Number];
 

MS Access позволяет редактировать некоторые JOIN запросы в зависимости от настроек. Поэтому просто удалите агрегатные функции ( COUNT , SUM ) и GROUP BY вернитесь к данным уровня единицы. Чтобы проверить, доступен ли запрос не только для чтения, запустите его в query design и посмотрите, можете ли вы редактировать любое значение в любом столбце (кроме автономеров) выводимых результатов. Даже прокрутите страницу вниз и проверьте, можете ли вы добавить запись.

 SELECT tblCustomers.Forename
     , tblCustomers.Surname
     , tblCustomers.Telephone
     , tblCustomers.[Customer ID]
     , tblTickets.[Ticket Type ID]
     , tblCustomerTypes.[Customer Type ID]
     , tblCustomerTypes.[Customer Type]
     , tblTicketTypes.[Ticket Type ID]
     , tblTickets.[Ticket Cost]
     , tblTickets.[Ticket Number] 

FROM ((tblCustomerTypes
INNER JOIN tblCustomers 
   ON tblCustomerTypes.[Customer Type ID] = tblCustomers.[Customer Type ID]) 
INNER JOIN tblTickets 
   ON tblCustomers.[Customer ID] = tblTickets.[Customer ID]) 
INNER JOIN tblTicketTypes 
   ON tblTickets.[Ticket Type ID] = tblTicketTypes.[Ticket Type ID] 
 

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

Рассмотрим другой, удобоваримый подход:

  1. Попросите пользователя ввести всю информацию о клиенте в одну форму.
     Record source: tblCustomers
     
  2. Используйте поле со списком для [Customer Type] . В MS Access comboxboxes может показывать пользователям человеческие значения, но скрывает и сохраняет соответствующий первичный ключ.
  3. Затем в другой форме или подчиненной форме введите все заявки.
     Record source: tblTickets
     
    • Если это другая форма, используйте поле со списком для [Customer ID] поля, чтобы выбрать из существующих клиентов.
    • Если подчиненная форма основной формы клиентов [Customer ID] неявно добавляется с новыми записями в подчиненную форму tickets.
  4. Используйте поле со списком для [Ticket Type] .
  5. Затем запустите свой агрегированный запрос только для просмотра результатов, а не для редактирования данных!

Ответ №2:

Разрешить редактирование формы?

Вы основываете форму НА ОДНОЙ ТАБЛИЦЕ. И на самом деле в БОЛЬШИНСТВЕ случаев вы не используете запрос для этой формы. Учитывая ваш снимок экрана — вы все равно редактируете только значения и столбцы из одной формы.

Если вам нужно включить, отредактировать, просмотреть, получить данные из дочерней связанной таблицы?

Затем закройте форму, над которой вы только что работали (ту, которая основана на ОДНОЙ таблице, А НЕ на запросе0.

Теперь вы создаете новую форму, скажем, для дочерней таблицы. Опять же, эта форма основана на ОДНОЙ таблице (а не на запросе). В этой форме будет отображаться информация о дочерних данных.

Как только эта форма будет выглядеть хорошо?

Затем вернитесь в «основную» форму, режим разработки, а затем из боковой панели навигации перетащите drop в «дочернюю» форму. Затем это станет вспомогательной формой.

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

Таким образом, у вас может быть основная форма, подобная этой:

введите описание изображения здесь

В приведенном выше примере нет SQL-запроса — просто форма, основанная на ОДНОЙ таблице.

Но допустим, я хочу отобразить дочернюю таблицу вариантов бронирования «тура».

Хорошо, мы создаем эту форму отдельно и основываем ее на дочерней таблице.

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

Теперь я понимаю это:

введите описание изображения здесь

И сказать, что я хотел показать людей, забронированных в номере?

Что ж, я снова ухожу, создаю форму, и СНОВА на основе одной таблицы.

И теперь я могу поместить эту форму в приведенную выше форму.

Итак, теперь мы должны сказать следующее:

введите описание изображения здесь

Итак, я на самом деле не писал НИКАКОГО sql. Каждая часть формы, которая должна отображать связанную (дочернюю таблицу) информацию, является просто еще одной 100% отдельной формой, которую я создал.

Затем я просто поместил эти дополнительные формы в эту одну основную форму на основе основной самой верхней записи.

Итак, где вы ошиблись?

Вы основываете форму на таблице. И НЕ запрос.

А если по какой-то странной причине вам нужен или используется запрос для формы? ОПЯТЬ же, он должен основываться на одной таблице.

Таким образом, в верхней форме (вспомогательной форме) отображаются люди, забронированные в номере. Остальная часть формы — это бронирование.

А затем в нижней части я добавляю таблицу (и откуда), в которой отображаются варианты бронирования.

Access автоматически извлечет дочерние записи, если вы настроите свои отношения для вас.