Access excel обновить все

1 / 1 / 0

Регистрация: 21.02.2015

Сообщений: 54

1

31.07.2017, 20:38. Показов 13553. Ответов 23


Студворк — интернет-сервис помощи студентам

Добрый день, подскажите, пожалуйста, как решить задачу:
Есть книга Excel «C:DataНовые сотрудники.xls». В этой книге есть лист «output», с таблицей данных (первая строка — название полей).
Есть база Access «Сотрудники». В этой базе есть таблица «test» с данными.

Что надо сделать:
Необходимо создать макрос в Excel либо запрос SQL в Access, который бы вставлял данные из листа output, в таблицу «test», причем если в таблице «test» есть уже такие данные (определяется по четырем ключевым полям), то их необходимо заменить. Т.е. не должно быть дублированых записей в таблице «test». Этим макросом я буду пополнять ежедневно данные в таблице «test», либо заменять уже существующие (на верные или скорректированные).

В чем проблема:
Я не знаю как создать таблицу (объект?) с дынными из Excel, что бы:
a. проверить есть ли такие же записи в таблице «test» (если есть, то удалить их из «test» и залить заново с новыми данными)
b. Вставить их в access.



0



mobile

Эксперт MS Access

26777 / 14456 / 3192

Регистрация: 28.04.2012

Сообщений: 15,782

31.07.2017, 21:54

2

Поскольку запрос к Excel необновляемый (патентные ограничения), то придется делать в 4 запроса:
1. удаление имеющейся временной таблицы
2. создание новой временной таблицы для импорта из Excel
3. обновление совпадающих по ключам записей
4. добавление новых в таблицу Test.

1. Запрос на удаление временной таблицы Temp

SQL
1
DROP TABLE Temp

2. Создание новой таблицы Temp из данных Excel

SQL
1
SELECT * INTO Temp FROM [output$] IN 'C:DataНовые сотрудники.xls'[excel 8.0; hdr=yes;]

3. запрос на обновление совпадающих по ключам записей

SQL
1
2
3
4
5
UPDATE test INNER JOIN Temp 
ON test.[ключполе1]=Temp.[ключполе1] AND test.[ключполе2]=Temp.[ключполе2] 
   AND test.[ключполе3]=Temp.[ключполе3] AND test.[ключполе4]=Temp.[ключполе4]
SET test.[обновлполе1]=Temp.[обновлполе1], test.[обновлполе2]=Temp.[обновлполе2], ...., 
    test.[обновлполеN]=Temp.[обновлполеN]

4. запрос на добавление новых в таблицу Test. Поскольку есть 4 ключевых поля по которым связываются таблицы, то если на этих полях задан составной индекс из всех 4 ключевых полей, то достаточно просто добавить инсертом данные в Test

SQL
1
2
3
INSERT INTO Test([ключполе1], [ключполе1], [ключполе1], [ключполе1], [обновлполе1], [обновлполе2], ..., [обновлполеN])
SELECT [ключполе1], [ключполе1], [ключполе1], [ключполе1], [обновлполе1], [обновлполе2], ..., [обновлполеN]
FROM Temp

Весь набор запросов легко вставить в процедуру и выполнять ее одним нажатием кнопки.



3



0 / 0 / 0

Регистрация: 13.02.2019

Сообщений: 15

01.02.2020, 19:25

3

Извините, но куда это всё вписывать, и как это будет выглядеть код в VBA по нажатию кнопки. Есть ли у кого пример.
Я что то поставлял в кнопку, вроде постарался адаптировать под свою задачу, но в итоге не вышло что-то.



0



Эксперт MS Access

7267 / 4469 / 288

Регистрация: 12.08.2011

Сообщений: 13,513

02.02.2020, 03:31

4

На вопрос «куда это вставить?» обычно отвечают однозначно. Но не буду здесь озвучивать, думаю дойдёт.
Не извиню. Извиняются, это когда на ногу случайно наступил, а когда проявляют свою полную неграмотность в деле, за которое берутся, тогда извините не прокатит. Заплатите кому надо и вам всё сделают, либо учите хотя бы азы: сначала SQL, потом MS Access для чайников.
Я уже не буду говорить про море примеров на форуме с кодом sql в vba. И не только на форуме.
И уж тем более промолчу, что в сообщении mobile VBA даже не пахнет



0



702 / 173 / 11

Регистрация: 16.01.2014

Сообщений: 548

02.02.2020, 08:31

5

Ну, можно, например, создать хранимые запросы и вызывать их из VBA командой CurrentDB.Execute
А вызов посадить на кнопку.



0



9727 / 4907 / 1195

Регистрация: 05.10.2016

Сообщений: 13,818

Записей в блоге: 1

02.02.2020, 08:54

6

Цитата
Сообщение от alvk
Посмотреть сообщение

И уж тем более промолчу, что в сообщении mobile VBA даже не пахнет

Правильно!
Но так эти запросы надо как то запускать ….
Плюс потребуется:
01. Диалог открытия импортируемого файла ( на форуме их море)
02. Дополнительная предварительная обработка импортированных данных

всё на VBA !

А чего мы тут обсуждаем??? — ТС-а давно тут уже нет — ненужно уже …



0



Эксперт MS Access

7267 / 4469 / 288

Регистрация: 12.08.2011

Сообщений: 13,513

02.02.2020, 10:57

7

Цитата
Сообщение от Eugene-LS
Посмотреть сообщение

ТС-а давно тут уже нет

суток не прошло — это давно?



0



779 / 461 / 79

Регистрация: 18.05.2016

Сообщений: 1,242

Записей в блоге: 4

04.02.2020, 11:41

8

Цитата
Сообщение от alvk
Посмотреть сообщение

суток не прошло

тема создана 31.07.2017, 21:38



0



2 / 1 / 0

Регистрация: 27.01.2015

Сообщений: 167

30.11.2021, 18:29

10

Не хочу новую тему создавать.
У меня немного другая задача: вставить в таблицу MyTable только те строки из файла Excel, которых там нет.
Программа (Макрос1) ругается на синтаксис SQL, подозреваю, что неверно ссылаюсь на лист Excel.
…конечно, можно завести временную таблицу, туда вставить всё из Excel, а потом делать запрос на обновление, но неужели одним запросом обойтись нельзя?



0



Eugene-LS

9727 / 4907 / 1195

Регистрация: 05.10.2016

Сообщений: 13,818

Записей в блоге: 1

30.11.2021, 20:23

11

Цитата
Сообщение от OrestBerserker
Посмотреть сообщение

Программа (Макрос1) ругается на синтаксис SQL, подозреваю, что неверно ссылаюсь на лист Excel.

Попробуйте:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Sub ww()
Dim sPth$, sSQL$ ', appE As Object
    
    sPth = "C:UsersRomanYandexDiskВДВUMOssvv.xlsx"
    'sPth = "d:Tempssvv.xlsx"
    
    If Dir(sPth, vbNormal) = "" Then
        MsgBox "Файл:" & vbCrLf & sPth & vbCrLf & _
            "не обнаружен!", vbExclamation, "Внимание!"
        Exit Sub
    End If
    sSQL = "INSERT INTO MyTbl ( ExtId, NzvSpc, Spc, Spz, VUS, VSpc ) " & vbCrLf & _
            "SELECT Q01.id, [Название специализации], " & vbCrLf & _
            "Q01.Spc , Q01.Spz, Q01.VUS, Q01.VSpc " & vbCrLf & _
            "FROM (" & vbCrLf & _
            "   SELECT * FROM [VDV$] AS xlData " & vbCrLf & _
            "   IN '" & sPth & _
                "'[Excel 12.0;HDR=yes;IMEX=1;ACCDB=Yes] " & vbCrLf & _
            ") AS Q01 " & vbCrLf & _
            "LEFT JOIN MyTbl ON Q01.id = MyTbl.ExtId " & vbCrLf & _
            "WHERE (ExtId Is Null);"
 
    Debug.Print sSQL
    
    DoCmd.RunSQL sSQL
    'CurrentDb.Execute sSQL
End Sub

Или так:

Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Sub ww()
Dim sPth$, sSQL$ ', appE As Object
 
    sPth = "C:UsersRomanYandexDiskВДВUMOssvv.xlsx"
    'sPth = "d:Tempssvv.xlsx"
 
    If Dir(sPth, vbNormal) = "" Then
        MsgBox "Файл:" & vbCrLf & sPth & vbCrLf & _
            "не обнаружен!", vbExclamation, "Внимание!"
        Exit Sub
    End If
  
    sSQL = "INSERT INTO MyTbl ( ExtId, NzvSpc, Spc, Spz, VUS, VSpc ) " & vbCrLf & _
        "SELECT id, [Название специализации], Spc, Spz, VUS, VSpc " & vbCrLf & _
        "FROM [VDV$] IN '" & sPth & _
            "'[Excel 12.0;HDR=Yes;Imex=1;] " & vbCrLf & _
        "WHERE (id Not In (SELECT ExtId FROM MyTbl));"
        
    Debug.Print sSQL
    DoCmd.RunSQL sSQL
End Sub



1



2 / 1 / 0

Регистрация: 27.01.2015

Сообщений: 167

30.11.2021, 20:59

12

Цитата
Сообщение от Eugene-LS
Посмотреть сообщение

Попробуйте:

Не могу не отозваться, оба примера работают.
Ещё спасибо не только за помощь, но и за очередные примеры красивого кода.
Бесспорно, SQL запрос, разделенный & vbCrLf & в ImmadiateWindow смотрится куда привлекательнее, чем длинная строка.



1



9727 / 4907 / 1195

Регистрация: 05.10.2016

Сообщений: 13,818

Записей в блоге: 1

30.11.2021, 23:09

13

Цитата
Сообщение от OrestBerserker
Посмотреть сообщение

за очередные примеры красивого кода.

Приятно читать.
Спасибо за добрые слова — Успехов!



0



shanemac51

Модератор

Эксперт MS Access

11336 / 4655 / 748

Регистрация: 07.08.2010

Сообщений: 13,484

Записей в блоге: 4

01.12.2021, 10:41

14

Цитата
Сообщение от OrestBerserker
Посмотреть сообщение

за очередные примеры красивого кода

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

Visual Basic
1
2
3
4
5
6
s1 = "INSERT INTO MyTbl ( ExtId, NzvSpc, Spc, Spz, VUS, VSpc ) " 
   s1=s1 &   " SELECT id, [Название специализации], Spc, Spz, VUS, VSpc " 
   s1=s1 &   " FROM [VDV$] IN '%sPth'[Excel 12.0;HDR=Yes;Imex=1;] "
   s1=s1 &   " WHERE (id Not In (SELECT ExtId FROM MyTbl));"
  s2=replace(s1,%sPth,sPth)
docmd.runsql s2



1



2 / 1 / 0

Регистрация: 27.01.2015

Сообщений: 167

01.12.2021, 11:00

15

shanemac51, вариант замены длинной строки на имя переменной действительно хорош, но имхо «собирание матрешки» с рекурсией (s1=s1 & bla-bla) порождает в Immadiate длинную строку, а разделители & vbCrLf & делают запрос во время отладки более читаемым.



0



Модератор

Эксперт MS Access

5122 / 2529 / 628

Регистрация: 12.06.2016

Сообщений: 6,749

01.12.2021, 11:10

16

Цитата
Сообщение от shanemac51
Посмотреть сообщение

предпочитаю иную запись

А для меня это совершенно нечитаемо.
Не хочу говорить «каша».



0



Модератор

Эксперт MS Access

11336 / 4655 / 748

Регистрация: 07.08.2010

Сообщений: 13,484

Записей в блоге: 4

01.12.2021, 12:14

17

Цитата
Сообщение от Capi
Посмотреть сообщение

А для меня это совершенно нечитаемо

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



0



9727 / 4907 / 1195

Регистрация: 05.10.2016

Сообщений: 13,818

Записей в блоге: 1

01.12.2021, 12:19

18

Цитата
Сообщение от Capi
Посмотреть сообщение

то совершенно нечитаемо.

… на вкус и цвет …- ну вы знаете …
Ку!



0



shanemac51

Модератор

Эксперт MS Access

11336 / 4655 / 748

Регистрация: 07.08.2010

Сообщений: 13,484

Записей в блоге: 4

01.12.2021, 12:22

19

Цитата
Сообщение от OrestBerserker
Посмотреть сообщение

запрос во время отладки более читаемым

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

Visual Basic
1
2
3
4
5
6
7
   s1 = "INSERT INTO MyTbl ( ExtId, NzvSpc, Spc, Spz, VUS, VSpc ) " 
   s1=s1 &   " SELECT id, [Название специализации], Spc, Spz, VUS, VSpc " 
   s1=s1 &   " FROM [VDV$] IN '%sPth'[Excel 12.0;HDR=Yes;Imex=1;] "
   s1=s1 &   " WHERE (id Not In (SELECT ExtId FROM MyTbl));"
   s2=replace(s1,%sPth,sPth)
   querydefs("wrem").sql=s2   ''' для поиска сложных ошибок
   docmd.runsql s2

и при необходимости запускаю wrem для поиска ошибки, что бывает крайне редко



1



Модератор

Эксперт MS Access

5122 / 2529 / 628

Регистрация: 12.06.2016

Сообщений: 6,749

01.12.2021, 12:50

20

Цитата
Сообщение от Eugene-LS
Посмотреть сообщение

на вкус и цвет …- ну вы знаете

Разумеется.
Я ведь и не навязываю.
Просто свое мнение высказываю.

И не говорю

Цитата
Сообщение от shanemac51
Посмотреть сообщение

у меня лучше



0



Привет всем!

Недавно попытался написать код обновления базы данных Access (accdb) данными из Excel макросом, который находится в Excel (примеры во вложенных файлах). Но при выполнении появляется ошибка  Run-time error ‘3704’:Операция не допускается, если объект закрыт. Пробовал добавить SET NOCOUNT ON в SQL-запрос, но получил ошибку синтаксиса SQL.
Как исправить ошибку 3704?
Правильные ли я подключил библиотеки:
Microsoft Access 15.0 Object Libray
Microsoft ActiveX Data Objects 2.8 Library
Microsoft ActiveX Data Objects Recordset 6.0 Library?

Правильный ли выбрал Provider=Microsoft.ACE.OLEDB.12.0?
OC — Windows 7 SP 1 64-bit, Office — 2016.
Подскажите, пожалуйста.

Вот код:

Код
Option Explicit
Dim EA As Excel.Application
Dim WB As Excel.Workbook
Dim WS As Excel.Worksheet
Dim strValue$, idcode&, strSQL$
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset

Public Sub transferAccPr()

Set EA = Excel.Application

EA.ScreenUpdating = False
EA.DisplayAlerts = False
EA.StatusBar = False

Set EA = Excel.Application
Set WB = EA.Workbooks("TestExcel.xlsm")
Set WS = WB.Worksheets("Лист1")

Set cn = New ADODB.Connection
cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:TestAccessBD.accdb;"
cn.Open

strValue = WS.Cells(2, 2).Value
idcode = WS.Cells(2, 1).Value

'strSQL = "SET NOCOUNT ON UPDATE Products SET [Item] = " & " '" & strValue & "'" & " WHERE Products.[CodeId]= 4"
strSQL = "UPDATE Products SET [Item] = " & " '" & strValue & "'" & " WHERE Products.[CodeId]= 4"

Set rs = cn.Execute(strSQL)

rs.Close

cn.Close

EA.ScreenUpdating = True
EA.DisplayAlerts = True

End Sub

Изменено: BretHard12022.02.2017 09:06:25

Вопрос:

Под “быстрым” я имею в виду использование SQL-запроса UPDATE, а не цикл через каждый набор записей.

Здесь Я нашел этот приятный запрос:

''Batch update (faster)
strSQL = "UPDATE [;Database=c:DocsDBFrom.mdb;].Table1 t " _
& "INNER JOIN [Sheet7$] s " _
& "ON s.id=t.id " _
& "SET t.Field1=s.Field1 " _
& "WHERE s.Field1<>t.Field1 "
cn.Execute strSQL

Однако этот пример используется при подключении из Access VBA для извлечения данных из Excel в Access.

В моем случае мне нужно будет подключиться из Excel VBA и использовать данные из того же файла Excel (именованный диапазон без заголовков), обновить данные Access. Данные имеют точно такую ​​же структуру, кроме заголовков.

Я не могу понять, как использовать этот метод UPDATE, так как он использует INNER JOIN для таблиц, который является одним из Access и другого в Excel. Существует только одно соединение (cn), так как он может читать и присоединяться к обеим таблицам? Я предполагаю, что он не нуждается в явном подключении к своим собственным данным Access, поэтому есть только одно соединение, сделанное с данными Excel. В моем случае я в Excel, поэтому я предполагаю, что мне нужно будет создать 2 подключения (к Access и Excel, поскольку Excel не является БД)? Могу ли я использовать этот пакетный метод обновления в своей ситуации (я бы добавил заголовки в Excel, если это помогло)?

Моя текущая ситуация:

Sub test_update()

Dim cn As Object    ''late binding - ADODB.Connection
Dim strSQL As String
Dim strFile As String
Dim strCon As String

Set cn = CreateObject("ADODB.Connection")

strFile = "C:TempTomTom.accdb"

''Consider HDR=Yes, so you can use the names in the first row of the set to refer to columns
''HDR=No;IMEX=1 - imex for mixed data types in a column
strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strFile & ";"
cn.Open strCon

''Batch update (fast)
strSQL = "UPDATE [;Database=" & strFile & ";].testQuery t " _
& "INNER JOIN [testSheet$ExternalData_1] s " _
& "ON s.ID=t.ID " _
& "SET t.col1=s.F2 " _
& "WHERE t.col1<>s.F2 "

cn.Execute strSQL


Set cn = Nothing

End Sub

Я получаю сообщение об ошибке Runtime Automation на cn.Execute strSQL, потому что я понимаю, что мой strSQL должен быть недействительным.

testSheet – это имя, имя листа и кодовое имя для листа.
ExternalData_1 – именованный диапазон.
testQuery – это имя запроса (просмотра) в Access, которое я хочу обновить.

Ответ №1

Я думаю, что вы ищете такой код:

Dim db As Object
Dim engine As Object
Set engine = CreateObject("DAO.DBEngine.120")
Set db = engine.OpenDatabase("C:yourdatabase.accdb")

Dim sql As String
sql = "UPDATE AccTable  AS acc " & _
" INNER JOIN (SELECT * FROM [NamedRange] IN ""C:yourexcelfile.xlsx"" ""Excel 12.0 xml;"" ) AS xls " & _
" ON acc.ID = xls.ID " & _
" Set acc.SomeField = xls.SomeField "

db.Execute sql

К сожалению, со всеми текущими версиями Access/DAO.DBEngine это приведет к появлению сообщения об ошибке You cannot edit this field because it resides in a linked Excel spreadsheet. The ability to edit data in a linked Excel spreadsheet has been disabled in this Access release., поскольку Microsoft намеренно отключила эту функцию по соображениям безопасности.

И да, это вздор, потому что вы даже не пытаетесь обновить данные в Excel, но все же это не работает. И, насколько я знаю, это относится ко всем возможным подходам для связывания Excel-листа с таблицей доступа в одном выражении SQL.

В качестве workaoaund вы можете либо попробовать импортировать данные Excel в таблицу базы данных Access (я не знаю, работает ли это по-прежнему!), а затем связать две таблицы Access для обновления, или вам придется прибегать к циклизации и обновлению отдельных записей.

How to Update Access Database from Ms Excel

In this tutorial, we discuss about how to update Access Database from Excel. As we know, we can import or export data between Ms Access and Ms Excel.

Link Ms Excel with Access Database

First thing to do is to link the spreadsheet in Ms Excel with the database in the Ms Access. To do this, follow the steps:

1. Open Ms. Excel. Go to Data tab, the select From Access.

2. Locate the database path in the dialog box.

3. In the pop up menu, choose the table to be imported. Then choose the table type.

4. Wait until the table is show up in the spreadsheet. And you are done with linking.

Linked Ms Excel Spreadsheet

Next, we’re linked the Ms Excel spreadsheet with the Ms Access database.

1. Open the Ms Access. Then, open the database that has just been imported in previous instructions.

2. Go to External Data tab, then, click Excel in Import & Link.

3. In the pop up menu, locate the new spreadsheet. Then in the option below, choose Link to data source by creating a linked table. Then click ok.

4. Choose the sheet to be linked. Hit next.

5. Lastly, rename the new linked table before hit the Finish button.

6. You are done! Now, there will be a new table that linked to Excel spreadsheet. Every time you update the data in Ms Excel, it will automatically updated to the Access database.

Link Database in Query

Note: If you have query, form or report using the excel database, you need to link the database in the query. To link the database, follow this steps:

1. Create the new query, then rename and save it.

2. Insert both tables: the original table and the linked excel table.

3. In Query Design, linked both table by the primary key.

4. Then in the box below, select the primary key from the original table. In Update To field, input the syntax: [ExcelTableName]![ColumnName]

Example: [TransactionExcel]![TransactionID]

The ExcelTableName is the linked excel table name, while the column name is the field name from the linked Excel table.

5. Then run the query. Now, every time you update the Excel spreadsheet, it will automatically not only update the database in the linked database, but the data in query, form, and report as well.

Related Access Database

  • https://database access-templates com/read/simple-church-membership-excel-database-template

Access Database Tags: #access database from excel file #auto update access database from excel #automatically update access database from excel #create access database from excel data #create access database from excel file #populate access database from excel form #update access database from excel cell #update access database from excel example #update access database from excel form #update access database from excel graph #update access database with excel data #update an access database from excel

  • «
  • Facebook
  • Twitter
  • Pin it
  • »

RRS feed

  • Remove From My Forums
  • Вопрос

  • Таблицу считает не обновляемой. Это что только до 2003 можно так делать было, а теперь все?

Ответы

  • Запросы на обновление в Access не работают, говорят что и не будут, очень плохо

    • Помечено в качестве ответа
      Кондратенко Александр
      10 октября 2014 г. 2:36

Все ответы

  • Видимо порядок для 2007 такой:

    1. Открываем файл Excel (в примере файл Пример.xlsx);

    2. Открываем файл Access (в примере файл 1.accdb);

    3. Вносим данные в файл Excel;

    4. Открываем таблицу в Access (в примере Пример)

    5. По необходимости, обновляем данные в Access, или закрываем таблицу и открываем таблицу вновь.

    Сохраните и распакуйте к себе архив с файл-примером Тест в корневую папку D:,
    пошагово выполните действия перечисленные выше, напишите результат.


    Да, я Жук, три пары лапок и фасеточные глаза :))

    • Изменено
      ЖукMVP, Moderator
      2 октября 2014 г. 6:04

  • Запросы на обновление в Access не работают, говорят что и не будут, очень плохо

    • Помечено в качестве ответа
      Кондратенко Александр
      10 октября 2014 г. 2:36

  • Запросы на обновление в Access не работают, говорят что и не будут, очень плохо

    Ваш ответ не содержит никакой полезной информации :(

    До обновления:

    После внесения изменений в таблицу Excel:


    Да, я Жук, три пары лапок и фасеточные глаза :))

  • Я надеялся что можно менять данные из Access, раньше это можно было

  • Изменение данных в Access с отражением в Excel, до изменения:

    После изменения в Access:


    Да, я Жук, три пары лапок и фасеточные глаза :))

    • Предложено в качестве ответа
      ЖукMVP, Moderator
      9 октября 2014 г. 15:55

Понравилась статья? Поделить с друзьями:
  • Access excel from web
  • Access excel from sql server
  • Access database from excel file
  • Access data in excel vba
  • Access and excel formulas