Помогите, плз, советом. Есть программка, созданная, похоже, на MS Access. Нужная мне информация содержится в файле MDB. Но самого Access на компе нет, и в ближайшее время не предвидится.
В этой БД кучка таблиц, нужную мне я вытаскиваю в Excel через простое подключение к внешним данным. Дальше я правлю в этой таблице нужные мне строки (только правлю содержимое, не убиваю и не добавляю строки). Суть правок - перевод интерфейса и пр. (программа многоязычная) с китайского или английского (или китайского варианта английского) на русский. Ну в общем не суть, просто вношу изменения в таблицу.
А вот дальше мне нужно засунуть измененную таблицу (достаточно только измененные строки) обратно в MDB, чтобы всё заверте... Как это сделать за один раз? На крайний случай, как это сделать по Worksheet_Change?
По форуму порылся, нашел только это. Но так как сам в ADO и SQL полный нуб, то поправить под себя макросы не выходит.
БД расположена тут: E:\Product.mdb и запаролена (предположим, пароль Pass1) Интересующая меня таблица называется _TRANSLATE, имеет поля ID, INDEX , English , Chinese , Russian, и т.д. языки (еще 13 шт.). Скорее всего, ID - ключевое поле. После импорта табличка становится таблицей Excel с именем "Таблица_Product"
Пытался адаптировать вот такой макрос:
Код
Private Sub Worksheet_Change(ByVal Target As Range)
Dim CN As Object 'ADODB.Connection
Dim RS As Object 'ADODB.Recordset
Dim sPath As String
sPath = "E:\Product.mdb"
Set CN = CreateObject("ADODB.Connection") 'New ADODB.Connection
CN.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & sPath & ";Persist Security Info=False;Password=""Pass1"""
'Debug.Print CN.ConnectionString
CN.Open
Set RS = CreateObject("ADODB.Recordset") 'New ADODB.Recordset
RS.Open "SELECT * FROM _TRANSLATION Where ID=" & Cells(Target.Row, 1).Value, CN, adOpenStatic, adLockOptimistic
If Not RS.EOF Then
RS.Fields("Russian").Value = Target.Value
RS.Update
'Else
' RS.AddNew
' RS.Fields("Russian").Value = Trim(Target.Value)
End If
RS.Close
CN.Close
End Sub
но ругается на немонопольный доступ на команде CN.Open Что не так, куды рыть?
не факт - но лучше проверить... если уже на 13-й строке ругается... ?
Цитата
Значением по умолчанию для ключевого слова PersistSecurity Info является false. Значение true или yes позволяет получить из строки соединения конфиденциальные данные (в том числе идентификатор пользователя и пароль) после открытия соединения. Если ключевое слово PersistSecurity Info равно false, то ненадежный источник не сможет получить доступ к конфиденциальным данным строки подключения.
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
Smiley, Спасибо!!!! Вот блин, а я уже на мыло изошел - и в квадратные скобки, и как только не. Замылился глаз. Все заработало. Осталось только теперь переделать под единовременную загрузку обратно в базу. Я так понимаю, надо либо циклом (что вроде как бээээ), либо другим способом. Есть какой-нибудь шустрый способ сразу выгрузить таблицу в mdb?
Максим Зеленский, тут не подскажу, никогда обратным действием не занимался Кстати, подключаться можно чуть попроще, мне кажется...
Код
Private Sub Worksheet_Change(ByVal Target As Range)
Dim CN As ADODB.Connection 'ADODB.Connection
Dim RS As ADODB.Recordset 'ADODB.Recordset
Set CN = New ADODB.Connection 'New ADODB.Connection
CN = "Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=E:\Product.mdb;Uid=Admin;Pwd=""Pass1"";"
CN.Open
Set RS = New ADODB.Recordset 'New ADODB.Recordset
RS.Open "SELECT * FROM _TRANSLATION Where ID=" & Cells(Target.Row, 1).Value, CN, adOpenStatic, adLockOptimistic
'-------
RS.Close
CN.Close
End Sub
Smiley написал: Достаточно просто указать имя таблицы в Access.
ну, вобщем, да... если оно без пробелов... но первый символ мне всё равно не нравится в названии таблицы... пока Максим не напишет, как правильно и как сработает... упс, уже написал... вот и замечательно
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
Максим Зеленский написал: Осталось только теперь переделать под единовременную загрузку обратно в базу. Я так понимаю, надо либо циклом (что вроде как бээээ), либо другим способом.
1) по-хорошему, надо UPDATE делать в самой sql-инструкции (пост TheBest'a) ... 2) по примеру "Экспорт из Excel в SQL Server" - примерно вариант "как бы" длинный - (пост Xapa6apga) - но только вставит, полагаю, без разбора - что дадите ему... 3) по примеру "импорт excel -access. VBA" - вариант INSERT INTO от anvg (Андрей) - тоже вставит в таблицу (уже существующую!) p.s. за вариантами 2-3 потом (или до того), полагаю, надо будет почистить саму БД.mdb от этих записей, ещё не исправленных... если это быстро для единовременной загрузки... p.p.s примеры этих 3х вариантов на выбор, если подойдут - однозначно с ходу не скажу, но, видимо, где-то в этом русле...
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
Максим Зеленский написал: Пока в результате простых вроде бы действий размер БД вырос в 2 раза...
насколько я поняла - такое бывает... потом в Access (2010): Работа с БД --> (Сервис) --> Сжать и восстановить БД... чтобы базу привести в нормальные размеры... но, в принципе, да, из xl править бд - видимо, не очень удобно? p.s. может быть, только если связать бд в access с xl (как внешним источником)... поправить, что надо... и разорвать эту связь в access... - но для этого тоже нужен access... если таким вариантом работает?
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
Максим Зеленский написал: Пока в результате простых вроде бы действий размер БД вырос в 2 раза...
видимо, для таких случаев встретился Compact Access Database ... смущает провайдер Jet.OLEDB, а не ACE.OLEDB для более старших версий xl... но при случае проверю - отпишусь, а пока просто кодом (вероятным)... раз уж стоял на повестке того дня этот вопрос
Скрытый текст
Compact Access Database
Код
'Copy the following code in a general module and call it with required parameters.
'This function returns 0 is successful else error number is returned
Option Explicit
Function CompactDB_JRO(strDBPath As String, Optional strDBPass As String = "") As Long
On Error GoTo ErrFailed
'Delete the existing temp database
If Len(Dir$(strDBPath & ".tmp")) Then
VBA.Kill strDBPath & ".tmp"
End If
With CreateObject("JRO.JetEngine")
If strDBPass = "" Then 'DB without password
.CompactDatabase "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _
strDBPath, "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strDBPath & ".tmp;Jet _
OLEDB:Encrypt Database=True"
Else 'Password protected db
.CompactDatabase "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & _
strDBPath & ";Jet OLEDB:Database Password=" & _
strDBPass, "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strDBPath & ".tmp;Jet _
OLEDB:Encrypt Database=True;Jet OLEDB:Database Password=" & strDBPass
End If
End With
On Error GoTo 0
VBA.Kill strDBPath 'Delete the existing database
Name strDBPath & ".tmp" As strDBPath 'Rename the compacted database
ErrFailed:
CompactDB_JRO = Err.Number
End Function
P.S. если колдовать над кодом и не использовать позднее связывание - то пригодится Tools/Reference -> Microsoft Jet and Replication Objects Library - как здесь
чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок - обратитесь к собеседнику на ВЫ - ответ на ваш вопрос получите - а остальное вас не касается (п.п.п. на форумах)
SELECT * | { [ DISTINCT | ALL ] { Поле данных } [,...] } FROM { таблица [ псевдоним ] } [,...] [ WHERE условие ] ..... SELECT возвращает как результат строки данных, которые создаются из данных, содержащихся в указанных исходных таблицах данных.
Для обратной загрузки используется команда: INSERT INTO таблица [ ( поле [,...] ) ] { VALUES ( Wertliste [,...] ) } - для добавления новых записей в БД UPDATE таблица SET { поле=значение } [,...] [ { WHERE условие } ] ; - для замещения текущих записей в БД
UPDATE _TRANSLATE SET ID =INDEX = 'Ваш INDEX',English = Ваша запись и т.д WHERE ID = 'ID' Данные лучше загрузить в массив (Подклюитесь к базе) и циклом записывать таблицу