|
|
|
| Есть база, пользователь с ней будет работать через RuntimeAcess.
Периодически в эту базу надо импортировать таблицу из *.xls файла.
Но в RuntimeAcess отсутствует меню (где можно было бы удобно выбрать внешние данные\excel...), можно ли как то включить это меню или надо реализовывать самому импорт??? Хотелось бы воспользоваться импортом который есть access. | |
|
| |
|
|
|
| это похоже то что нужно
http://hiprog.com/index.php?option=com_content&task=view&id=251661628 | |
|
| |
|
|
|
| тогда второй вопрос а есть какой нибудь пример аналога "импорта данных в конец существующей таблицы"?
docmd.transferspreadsheet
таких параметров не имеет.
а оказалось проще простого эта команда по автомату пишет в конец существующей таблицы если она есть! | |
|
| |
|
|
|
| что у меня не получилось пока это избежать лишнего экспорта - импорта (импортирую файл из excel, обрабатываю, экспортирую на винт, импортирую в конец существующей таблицы отредактированный файл из excel).
может кто подскажет (хочется чтобы было импортирую файл из excel, обрабатываю, добавляю отредактированные записи в конец существующей таблицы )?
есть таблица1 и таблица 2 в базе access (набор столбцов одинаков).
нужно переписать все данные таблица 2 в конец таблицы 1 с сохранением того что в ней было до этого (то есть выполнить грубо таблица1 union таблица 2).
заранее спасибо | |
|
| |
|
|
|
| Запрос на добавление ( INSERT INTO) именно это и сделает - добавит записи из Т2 в конец Т1. | |
|
| |
|
|
|
| что то типа
docmd.runsql "insert into t1 select * from t2"
так? | |
|
| |
|
|
|
| можно прямо из файла эксель | |
|
| |
|
|
|
| сразу нельзя надо сначала обработать данные которые были в исходном экселе. | |
|
| |
|
|
|
| обрабатывать после добавления | |
|
| |
|
|
|
| тогда время обработки будет постоянно увеличиваться, так как допустим импортируется файл из 25000 строк. если обработчик проходит по ним то это одно время
а теперь если мы его сначала вкинули в конец существующей таблицы а вней уже было 300000 строк, тогда обработчик будет проходить по 325000 строкам - а это уже большее время. | |
|
| |
|
|
|
| А поставить флаг обработано/нет никак? | |
|
| |
|
|
|
| то есть добавить столбец в таблицу? а смысл все рано нужно пройти по всем записям и отобрать где есть флаг где нет...
а чем плох импорт из эксель во временную таблицу и потом ее стирание после обработки и добавления записей в основную? | |
|
| |
|
|
|
|
а чем плох импорт из эксель во временную таблицу и потом ее стирание после обработки и добавления записей в основную?
|
1) импорт во временную таблицу ведет к разбуханию БД
2) лишние манипуляции с данными увеличивают риски ошибок
3) просто потери времени на лишние неэффективные операции
а вообще рекомендуется сначала готовить таблицу Excel а потом перегонять уже подготовленные данные | |
|
| |
|
|
|
|
...все рано нужно пройти по всем записям и отобрать где есть флаг где нет...
|
Jet это сделает моментально, если его грамотно об этом попросить. | |
|
| |
|
|
|
| подскажите тогда как? научите избежать лишнего импорта.
исходная задача, есть Т1 (а,б,в), Есть файл xls с заполненными 3-мя столбцами (первая строка наименования столбцов соответственно "а,б,в").
Нужно обработать некоторые данные содержащиеся xls (например, если а=1, то в ячейку б копируется значение из в, и еще пара преобразований).
я делаю так, импортирую Т2, обрабатываю, копирую запросом в конец Т1, удаляю Т2.
можно было бы потом просто сжать и восстановить базу, но у юзера такой возможности не будет - так как там только runtime access (поэтому конечно база пухнет:(:(:() | |
|
| |
|
|
|
|
подскажите тогда как? научите избежать лишнего импорта.
|
самое простое что можно посоветовать - импортировать данные во временные таблицы во временных БД, чтобы не допускать распухания основной БД
подключать нужный файл эксель для импорта данных можно либо выбирая его через диалог выбора файла либо просто переименовывая нужный файл эксель и подставляя его в нужное место
вообще недостаточно данных для того, чтробы рекомендовать что-то конкретное.
в общем случае запрос на линковку к файлу эксель (IMEX=2) выглядит так (например):
SELECT *
FROM [ReportPage1$] IN 'F:\Report.xls'[Excel 8.0;HDR=YES;IMEX=2];
|
| |
|
| |
|
|
|
| может проще программно сжать базу при выходе? так же тоже можно сделать?
а вообще вот мой код, самое долгое время в нем занимает работа со столбцами в рекордсете - rst, ну и после удаления временной таблицы база распухает, нужно сжимать
может что то я неправильно делаю?
Private Sub but_FormatNumber_Click()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim tabName As String
Dim i, j, k As Integer
Dim frm As Form_usys_f_parserProgressBar
Dim strFD As Variant
Set db = CurrentDb()
'проверка выбора таблицы для обработки парсером
If Me.TmpFlag Then
tabName = "usys_callstmp"
'выбор файла-лога для обработки парсером и его импорт
If IsExistTab(tabName) Then db.Execute "DROP TABLE " & tabName
strFD = xlsFD()
If Not IsNull(strFD) Then DoCmd.TransferSpreadsheet acImport, 8, tabName, strFD, True, "" Else Exit Sub
Else: tabName = "usys_calls"
End If
'проверка наличия таблицы
If IsExistTab(tabName) Then
'инициализируем форму с ProgressBar
Set frm = New Form_usys_f_parserProgressBar
With frm
.Modal = True
.Visible = True
.InAction = True
End With
Set rst = db.OpenRecordset(tabName)
rst.MoveFirst
While Not rst.EOF
With rst
For i = 0 To .Fields.Count - 1
'выбор столбца с именем Number
If .Fields(i).name = "Number" Then
If (.Fields(i).Value = "incoming") Then
For j = 0 To .Fields.Count - 1
'выбор столбца с именем CallerId
If .Fields(j).name = "CallerId" Then
If Not IsNull(.Fields(j).Value) Then
.Edit
.Fields(i).Value = "8" & .Fields(j).Value
.Update
Else
.Edit
.Fields(i).Value = "н/а"
.Update
End If
End If
Next j
ElseIf (Left(.Fields(i).Value, 9) = "internal-") Then
.Edit
.Fields(i).Value = Right(.Fields(i).Value, Len(.Fields(i).Value) - 9)
.Update
End If
'проверяем былали нажата кнопка прервать
If Not frm.InAction Then MsgBox "Работа парсера прервана пользователем!": Exit Sub
'передача управления системе, которая позволяет отрабатывать ProgressBar
DoEvents
End If
Next i
End With
rst.MoveNext
Wend
rst.Close
If Me.TmpFlag Then
'добавляем обработанные парсером записи в основную таблицу логов
DoCmd.SetWarnings False
DoCmd.RunSQL "INSERT INTO usys_calls SELECT * FROM " & tabName
db.Execute "DROP TABLE " & tabName
DoCmd.SetWarnings True
End If
db.Close
'закрытие формы с ProgressBar
DoCmd.Close acForm, "usys_f_parserProgressBar"
MsgBox "Работа парсера завершена успешно!"
Else
MsgBox "Отутствует таблица """ & tabName & """ Необходимо создать данную таблицу.",
End If
DoCmd.Close acForm, Me.name
End Sub | |
|
| |
|
|
|
| Чисто по ТЗ:
sSQL = "INSERT INTO T1 (а,б,в) SELECT T2.[a], IIF(T2.[a]=1, T2.[в], T2.[б]), T2.[в] FROM [Лист1$] As T2 IN 'C:\MyFile.xls' [Excel 8.0;HDR=Yes;IMEX=1]"
CurrentDB.Execute sSQL
| Если "еще пара преобразований", то выражения в инструкции SELECT можно усложнить | |
|
| |
|
|
|
| тут еще надо выкидывать как то строчку с именами столбцов | |
|
| |
|
|
|
| HDR = YES/NO это и есть первая строчка с именами столбцов
Yes - включаем в таблицу
No - выкидываем | |
|
| |
|
|
|
| понял, попробую в свой код вкрутить | |
|
| |