Хобрук: Ваш путь к мастерству в программировании

не удалось обновить поле таблицы доступа с помощью VBA

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

Option Compare Database

Public Function GetUserName() As String
 Dim obj1 As Object
 Set obj1 = CreateObject("WScript.Network")
 GetUserName = DLookup("[BAFUser]", "BAF_User", "[BRID] = '" & obj1.UserName & "'")
 Set obj1 = Nothing

End Function

Private Sub Form_BeforeInsert(Cancel As Integer)
 Owner2 = CreateObject("WScript.Network").UserName
 AdvisorName = GetUserName

End Sub

Private Sub Form_Load()
 Me.DataForm.Form.Recordset.MoveLast

End Sub

Private Sub SaveBtn_Click()
 RunCommand acCmdSaveRecord
 Me.Requery
 Me.DataForm.Form.Recordset.MoveLast
End Sub

Я могу получить значение в поле «владелец», но не в поле «AdvisorName». Что может быть возможной причиной этого? есть ли ошибка в моем коде или есть ли лучший способ сделать это?

05.12.2017

  • AdvisorName = GetUserName Что это делает? 05.12.2017
  • он сохранит значение переменной GetUserName в столбце AdvisorName в таблице, ну, этот код не работает, я попытался сохранить AdvisorName = hello world, он тоже не сохраняет его. но его сохранение в Owner. 05.12.2017
  • Это не то, как вы сохраняете что-то в таблице. Я не знаю, как Владелец что-то получает, потому что это тоже неверно. Вы сохраняете эти значения только в переменных. Они также имеют частную область действия, поэтому значение исчезает почти сразу и никогда не взаимодействует с вашей формой. Не могли бы вы предоставить более подробную информацию о вашей форме? Привязаны ли элементы управления к вашей таблице? 05.12.2017
  • RunCommand acCmdSaveRecord эта строка фиксирует текущую запись формы в таблице, поэтому я предполагаю, что она привязана, что излишне, поскольку связанная форма делает это автоматически. 05.12.2017
  • Да, стол привязан. Итак, как правильно сохранить значение в столбце при каждой записи? @MoondogsMaDawg Извините, я новичок в Access, но я могу предоставить вам все детали, которые вам нужны, чтобы помочь мне. 05.12.2017
  • Для этого вам не нужен код. Access сделает это автоматически после перемещения текущей записи. Итак, вы вводите данные в свою форму, затем нажимаете кнопку навигации, чтобы перейти к другой записи (новой, старой, не имеет значения). В этот момент Access добавит вашу таблицу с контрольными значениями в вашей форме. В противном случае вам нужно написать оператор sql, манипулировать querydef или использовать набор записей для сохранения записи в таблицу (все они используют оператор sql). Найдите vba execute sql append, и вы найдете множество примеров, но в вашем случае это не обязательно. 05.12.2017
  • Является ли AdvisorName элементом управления формой? Или вы пытались получить это значение в таблице только в коде? 05.12.2017
  • Нет, я хочу установить это значение, используя код, а не элементы управления формы, я не хочу, чтобы пользователь видел этот элемент управления, он должен автоматически отправляться для каждой записи для всех пользователей. 05.12.2017
  • Я отключил кнопки навигации и другие кнопки. Это командная кнопка, которая сохраняет данные, как вы можете видеть, код SaveBtn_Click() 05.12.2017
  • Хорошо, можете ли вы добавить имя таблицы, столбцы, типы к своему вопросу. Я с удовольствием отредактирую код. 05.12.2017
  • Имя таблицы - Mau_con У меня много столбцов, но я отправляю данные через код только для двух столбцов AdvisorName , Owner , оба имеют текстовый тип. И у меня есть переменная в моем коде GetUserName, VBA должен проверять значение GetUserName каждый раз перед отправкой записи и сохранение значения этой переменной в столбце AdvisorName. 05.12.2017
  • надеюсь понятно объяснил :) 05.12.2017

Ответы:


1

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

Я скопировал код с кнопки сохранения, чтобы восстановить состояние формы после ввода. Это должно привести к резервному копированию последней записи, но от типа курсора набора записей будет зависеть, будет ли представлена ​​сохраненная запись или нет (она может вернуться назад).

Private Sub Form_BeforeInsert(Cancel As Integer)

    Dim qdf As QueryDef
    Dim Owner2 As String
    Dim AdvisorName As String

    Owner2 = CreateObject("WScript.Network").UserName
    AdvisorName = GetUserName

    Set qdf = CurrentDb.CreateQueryDef("", "INSERT INTO Mau_con (Owner, AdvisorName) VALUES ('" & Owner2 & "', '" & AdvisorName & "')")
    qdf.Execute
    Me.Requery
    Me.DataForm.Form.Recordset.MoveLast
    Set qdf = Nothing

End Sub
05.12.2017
  • Выдает ошибку компилятора, в чем может быть причина? 05.12.2017
  • Извините, я забыл первый аргумент qdf (имя запроса, которого не существует, поэтому я использовал пустую строку). 05.12.2017
  • Кроме того, в строке sql не должно быть двойных кавычек. Я снова обновил ответ. 05.12.2017
  • Теперь он не дает ошибки, но также ничего не сохраняет в полях AdvsiorName и Owner. 05.12.2017
  • Шаг через код. Имеют ли переменные значения до qdf.Execute? Установите точку останова на qdf.Execute и, когда она остановится, введите: ?qdf.sql в ближайшее окно и опубликуйте результат. 05.12.2017
  • извините, я не знаю, как это сделать, дайте мне просто настроить это, и я скажу, что это дает 05.12.2017
  • извините, я не могу найти соответствующую статью, чтобы узнать, как это сделать, не могли бы вы объяснить 05.12.2017
  • Откройте VBE, найдите этот код и слева от qdf.Execute щелкните левой кнопкой мыши сбоку окна. Должна появиться красная точка. Теперь сохраните код, введите представление формы в своей форме и запустите код для запуска. Когда это произойдет, VBE появится, когда он попадет в красную точку. Затем введите ?qdf.sql в часть VBE с надписью Immediate Window и нажмите Enter. Он должен ответить примерно так: INSERT INTO Mau_con (Владелец, AdvisorName) VALUES ('xxxx', 'xxxx'). Вставьте этот вывод сюда. 05.12.2017
  • Точка останова выглядит следующим образом: это 05.12.2017
  • хорошо, после сохранения красной точки я снова перешел к своей форме, и как только я набрал что-нибудь в форме, я перешел к VBA с желтой стрелкой на красной точке, но не появилось всплывающее окно, чтобы что-то написать, мне нужно написать это рядом стрелка сейчас? 05.12.2017
  • Нет, ближайшее окно не открыто. Ctrl + G должен сделать его всплывающим 05.12.2017
  • ОК, я получил его, результат после того, как он говорит об ошибке компиляции: ожидаемая функция или переменная 05.12.2017
  • и если я запускаю немедленное окно без запуска кода, он говорит об ошибке 424: требуется объект 05.12.2017
  • Ошибка 424 имеет смысл, потому что qdf не будет существовать, если код не запущен. Вы использовали вопросительный знак впереди? ?qdf.sql Какую версию Access вы используете? Проверьте каждую из ваших переменных, поэтому в режиме перерыва попробуйте ?Owner2, ?AdvisorName 05.12.2017
  • да, я использовал вопросительный знак, и у меня есть доступ к 2010, дай мне попробовать и другие 05.12.2017
  • Ну, я попробовал? Owner2.sql и? AdvisorName.sql, он возвращает то же самое, должен ли я попытаться ввести в форму и позволить ему вызвать разрыв кода, тогда я должен ввести? 05.12.2017
  • Просто выполните ?Owner2 и ?AdvisorName. .Sql является только свойством объекта qdf. 05.12.2017
  • Да, активируйте код и подождите, пока он не достигнет точки останова, а затем введите в ближайшее окно. 05.12.2017
  • если я просто наберу ?Owner или ?AdvisorName, это не сработает, нажатие кнопки ввода просто перейдет к следующей строке. 05.12.2017
  • Это означает, что они пусты! Бинго! 05.12.2017
  • Для проверки вы можете попробовать ?IsNull(AdvisorName), и он должен ответить TRUE. 05.12.2017
  • Чтобы протестировать свои библиотеки, вставьте этот ответ в модуль и запустите его. Печатает ли он правильные значения? 05.12.2017
  • Возвращает false с помощью ?IsNull(AdvisorName) 06.12.2017
  • А как насчет ?AdvisorName = " " 06.12.2017
  • Вы хотите, чтобы я использовал этот ответ в совершенно новом модуле, а не в модуле этой формы, верно? 06.12.2017
  • Он вернул false с ?AdvisorName = 06.12.2017
  • Вы можете запустить его где угодно. Я обычно использую модуль, чтобы сохранить исходный код в чистоте. Суть здесь в том, что вам нужно убедиться, что ваши переменные содержат допустимую строку, иначе qdf завершится ошибкой и не запишет в таблицу. Я тоже не знаю, почему ?qdf.sql не работает. Я не могу воспроизвести проблемы, которые вы видите. 06.12.2017
  • Я попробовал приведенный ниже код в модуле тестовой формы, он сработал: Option Compare Database Public Function GetUserName() As String Dim obj1 As Object Set obj1 = CreateObject("WScript.Network") GetUserName = DLookup("[BAFUser]", "BAF_User", "[BRID] = '" & obj1.UserName & "'") Set obj1 = Nothing End Function Private Sub Form_Load() Dim AdvisorName As String AdvisorName = GetUserName MsgBox "Welcome " & AdvisorName End Sub 06.12.2017
  • извините за беспорядок, но да, он показывает значение AdvisorName в msgbox 06.12.2017
  • Откройте конструктор запросов в режиме SQL и вставьте следующее, обновляя значения My.. фактическими значениями (сохраняйте одинарные кавычки): INSERT INTO Mau_con (Owner, AdvisorName) VALUES ('MyOwner', 'MyAdvisor'). Затем запустите его. Запись добавлена ​​в таблицу? 06.12.2017
  • он говорит, что не может добавить все записи в запрос на добавление. 06.12.2017
  • Похоже, мы не соответствуем требованиям к столу. Вы сказали, что хотите добавить только два столбца, но для таблицы может потребоваться больше. Вам нужно проверить каждый столбец, чтобы увидеть, для каких из них установлено значение «Да». Если требуются какие-либо другие столбцы, кроме этих, вам придется либо добавить их в этот запрос, либо удалить требование. 06.12.2017
  • Да, извините, одно из полей было установлено как обязательное, теперь я установил для него значение «нет», и оно успешно сохранило запись в таблице, я надеюсь, что мы близки к тому, чтобы исправить это сейчас :) и да, у меня есть более 10 полей 06.12.2017
  • Хаха да я тоже. Попробуйте запустить код еще раз, надеюсь, он сработает. Я просто надеюсь, что форма не испортится, потому что это еще одна банка червей. 06.12.2017
  • Хорошо, дело в том, что код сработал, большое спасибо, но сначала он ввел эти два поля в 2 строки, а затем в третьей строке я вижу данные, которые я ввел в форму, они не приходят в одну строку, еще одна вещь, которую я заметил, что с тех пор, как вы заставили меня изменить мой код, он автоматически обновляет форму один раз, когда я пытаюсь ввести информацию, попытаемся ли мы удалить запрос? 06.12.2017
  • Да, извините, я забыл, что это было до вставки. Это ваш код, делайте что хотите. Я поместил это туда для страховки, так как я недостаточно знаю о вашей форме, чтобы знать, как поддерживать ее состояние. Если это не нужно, удалите его. 06.12.2017
  • так что раньше данные поступали в третьей строке, теперь они поступают во вторую строку, а в первой строке у меня есть значение AdvisorName, так что я должен использовать другую функцию или что? 06.12.2017
  • Я не знаю, что вы имеете в виду под второй и третьей строкой. В твоей форме? Я не знаю, как выглядит ваша форма и что она отображает. 06.12.2017
  • когда я нажимаю кнопку отправки, он создает строку в таблице с заполненными только AdvisorName и Owner и вторую строку с деталями, которые я помещаю в форму, он создает две строки в таблице, он не фиксирует данные в одной строке 06.12.2017
  • как вы думаете, я должен написать свой запрос на вставку при каждом нажатии кнопки отправки? 06.12.2017
  • Ах, я понял. Можно ли отвязать форму? Вы можете переместить код в процедуру сохранения, но это не остановит вторую запись. Если сделать источник управления для каждого поля пустым, это предотвратит вторую строку, но вам придется написать процедуру для сохранения других полей, потому что вы потеряете функциональность. 06.12.2017
  • тогда мне нужно писать коды для каждого поля? Я боюсь, что чем больше я полагаюсь на код VBA, тем больше шансов, что пользователь получит ошибку. Итак, как лучше всего это сделать сейчас? 06.12.2017
  • Вчера вечером у меня появилась другая идея. Создайте скрытый элемент управления формой, который вызывает GetUserName. Вам может понадобиться повторно запросить его в определенные моменты, но вы можете привязать его к таблице и избавиться от vba, сохраняющего запись. В противном случае вам придется решить, использовать ли связанную или несвязанную форму. Ошибки с несвязанными формами действительно возникают только в том случае, если вы не планируете все возможные варианты, что делает его более эффективным, но гораздо более гибким. Связанные формы делают дизайн простым и легким, но они немного менее гибкие. Я бы попробовал сначала сделать контроль имени пользователя. Если вы можете заставить его работать, вы можете использовать связанную форму. 06.12.2017
  • На самом деле я сделал то же самое прошлой ночью после того, как избавился от двойной строки. Теперь он работает нормально, но всякий раз, когда я нажимаю клавишу f5, он теряет значение, вот код, который я использовал, Private Sub Form_Load() Me.AdvisorName2.Value = GetUserName Me.DataForm.Form.Recordset.MoveLast End Sub 06.12.2017
  • хм, странно. Поставьте там точку останова и убедитесь, что GetUserName действительно срабатывает. Я не вижу никаких проблем с этим кодом, и f5 определенно запускает событие Form_Load при переключении из режима разработки, поэтому я не вижу, где еще может произойти сбой. 06.12.2017
  • Хорошо, я попробовал, когда я открываю форму в первый раз, она срабатывает и останавливается в точке останова, и я проверил, что GetUserName также имеет желаемые значения, но когда я обновляю форму с помощью кнопки f5, она не срабатывает в точке останова, это не останавливает все, кажется, что он не вызывает Form_Load() при нажатии f5, я не понимаю, почему это происходит так, я задал другой вопрос по этому поводу, может быть, мы можем обсудить здесь 07.12.2017
  • Новые материалы

    Не зря же это называют интеллектом
    Стек — C#, Oracle Опыт — 4 года Работа — Разведывательный корпус Мне пора служить Может быть, я немного приукрашиваю себя, но там, где я живу, есть обязательная военная служба на 3..

    LeetCode Проблема 41. Первый пропущенный положительный результат
    LeetCode Проблема 41. Первый пропущенный положительный результат Учитывая несортированный массив целых чисел, найдите наименьшее пропущенное положительное целое число. Пример 1: Input:..

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

    Управление состоянием в микрофронтендах
    Стратегии бесперебойного сотрудничества Микро-фронтенды — это быстро растущая тенденция в сфере фронтенда, гарантирующая, что удовольствие не ограничивается исключительно бэкэнд-системами..

    Декларативное и функциональное программирование в стиле LINQ с использованием JavaScript с использованием каррирования и генератора ...
    LINQ - одна из лучших функций C #, которая обеспечивает элегантный способ написания кода декларативного и функционального стиля, который легко читать и понимать. Благодаря таким функциям ES6,..

    Структуры данных в C ++ - Часть 1
    Реализация общих структур данных в C ++ C ++ - это расширение языка программирования C, которое поддерживает создание классов, поэтому оно известно как C с классами . Он используется для..

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