2017-01-11 2 views
0

В Excel 2010. Я пытаюсь написать/обновить некоторые ячейки на основе некоторых фильтров в той же книге, которая выполняет макрос; для простоты я уменьшил запрос до того, что вы можете видеть. Этот код работает, но только когда книга закрыта (проверена в другой книге).Обновление Excel с помощью ADODB с рабочей книгой Open

Dim libro As Workbook 
Set libro = ActiveWorkbook 
esteLibro = libro.Name 

Dim cnCaja As ADODB.Connection 
Dim rsCaja As ADODB.Recordset 
Set cnCaja = New ADODB.Connection 
Set rsCaja = New ADODB.Recordset 
cnCaja.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _ 
    "Data Source='" & esteLibro & "';" & _ 
     "Extended Properties='Excel 12.0;HDR=Yes;ReadOnly=False';" 

Dim consCaja As String 
consCaja = "Update [Base$A3:T100000] Set INVERSIONES = 1000 " 
rsCaja.Open consCaja, cnCaja, adOpenStatic, adLockOptimistic 

В случае выполнения из другой книги колонки «ИНВЕРСИОНЫ» будут иметь свои пустые ячейки, измененные на 10000; но из тех же книг я получил ошибку:

'-2147217865 (8004e37)' The Microsoft Access database engine could not find the object '[Base$A3:T100000]'. Make sure the object exists and that you spell its name and the path name correctly. If '' is not a local object, check your network connection or contact the server administrator.

Это вся строка соединения:

Debug.Print cnCaja.ConnectionString 

Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin; Data Source=Danny_Diario.xlsm;Mode=Share Deny None; Jet OLEDB:System database="";Jet OLEDB:Registry Path=""; Jet OLEDB:Database Password="";Jet OLEDB:Engine Type=35; Jet OLEDB:Database Locking Mode=0;Jet OLEDB:Global Partial Bulk Ops=2; Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password=""; Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False; Jet OLEDB:Don't Copy Locale on Compact=False; Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False; Jet OLEDB:Support Complex Data=False; Jet OLEDB:Bypass UserInfo Validation=False;

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

consCaja = "Select * from [Base$A3:T100000] Where Fecha = #" & fechaBase & "# and Empresa = ""Empresa"" and Banco = ""Banco""" 
rsCaja.Open consCaja, cnCaja, adOpenForwardOnly, adLockReadOnly 

Do While Not rsCaja.EOF 
    MsgBox (rsCaja("Empresa").Value & vbNewLine & rsCaja("Banco").Value & vbNewLine & rsCaja("INVERSIONES").Value) 
    rsCaja.MoveNext 
Loop 

Наконец, можно ли обновить Excel с помощью ADODB с открытой книгой? Если да, что я делаю неправильно, или как мне это разрешить?

+0

Соединительные строки нуждаются в полном пути. Измените верхнюю строку на: 'esteLibro = libro.FullName'. Даже до сих пор я сомневаюсь, что вы можете обновить с помощью открытой книги. – Parfait

+0

Я могу читать, поэтому полный путь не нужен. Но даже с полным путем, я все еще имею ту же ошибку. И я не смог найти источник, который говорит мне, что это невозможно. – Jedicillo

ответ

0

Рассмотрите возможность использования только для чтения SELECT по существующим данным открытой книги. По разным причинам доступа к записи в файлах Excel, являющийся плотным файловым кэшированным приложением для хранения данных, может не иметь средства, например базы данных, для открытия приложения, а текущие данные обновляются синхронно.

Ниже устанавливает SELECT запрос для вас, чтобы отразить текущую структуру с одним изменением прохождения постоянной, 1000, и назначая его к INVERSIONES столбца псевдоним в текущей позиции столбца. Здесь также можно легко разместить условную логику IIF. Кроме того, запустите запрос и дамп в новом листе. Затем удалите/архивируйте текущий рабочий лист и сохраните книгу.

Dim cnCaja As New ADODB.Connection 
Dim rsCaja As New ADODB.Recordset 
Dim consCaja As String 

esteLibro = ActiveWorkbook.FullName 
cnCaja.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _ 
      "Data Source='" & esteLibro & "';" & _ 
      "Extended Properties='Excel 12.0;HDR=Yes;';" 

consCaja = "SELECT Col1, Col2, Col3, '1000' AS INVERSIONES, Col4, Col5, Col6" & _ 
      " FROM [Base$A3:T100000]" 
rsCaja.Open consCaja, cnCaja 

Worksheets("Base").Range("A3").CopyFromRecordset rsCaja 

rsCaja.Close: cnCaja.Close 
Set rsCaja As Nothing: Set cnCaja As Nothing 
+0

Это упрощенный запрос. Реальный запрос выглядит примерно так: '' consUpdate = "Обновить [Base $ A3: T100000] Установить INVERSIONES = prMonto" & _ '' Где Empresa = prEmpresa и BANCO = prBanco и Fecha = prFecha "' Я хочу использовать параметризованный запрос, для фильтров в SQL, поэтому мне нужен ADODB. Между данными, которые я хочу обновить, могут быть пробелы, поэтому я не могу использовать range.copy ... Другой вариант, на данный момент, состоит в том, чтобы просто прокрутить строки, чтобы увидеть, соответствуют ли данные моим параметрам, но я думаю это будет намного медленнее со временем и приростом данных. – Jedicillo

+0

Как уже упоминалось, вы можете использовать 'IIF()' для установки логики и передачи необходимых параметров: 'SELECT Col1, Col2, Col3, IIF (Empresa =? AND BANCO =? AND Fecha = ?,?, INVERSIONES) AS NewInversiones, Col4 , Col5, Col6 FROM [Base $ A3: T100000] '. И я не совсем понимаю, почему «CopyFromRecordset» не работает, так как это будет точная копия самого табличного диапазона в разделе «FROM», который вернется в начале «Base $ A3». – Parfait

+0

Теперь я понимаю. Но мне все равно не нравится переписывать все. Спасибо. Я полагаю, что то, что я хочу сделать, невозможно, поэтому я просто использую старый 'Для каждого r в ws.Range(). Строки. – Jedicillo