Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > MS Access > VBA Access Экспорт несколько таблиц в листы одной


Автор: Ethex 3.7.2017, 11:32
Доброго времени суток.
Сюда будут приложены две формы Access. Одной из них я "вдохновлялся", другая моя (по названию несложно будет понять какая из них какая).  

Однако, не идентичны. Мне нужно предоставить пользователю возможность предварительно выбрать нужные таблицы для экспорта, а не просто отправлять все разом. Колличество нужных таблиц может варьироваться. Имеется два списка. В первый нажатием кнопки выводятся имена всех таблиц. Во второй список кликом отправляются нужные. Соответственно, процедура экспорта обращается ко второму списку.

Проблема: Изначально я забыл присвоить значение переменной cnt. Процедура проходила, но экспортируя только одну таблицу, чьё имя первое в списке. После того как присвоил, при попытке экспорта более одной таблицы выдаёт "ошибка 1004: Нельзя присвоить листу имя, совпадающее с именем другого листа, библиотеки объектов или книги, на которую ссылается Visual Basic" в строке:
Код

wrk.Sheets(i + 1).Name = t
  
При первых попытках пару раз вместо этой выдавало другую ошибку. Номер не запомнил, но ругалась на FROM в:
Код

Set rst = db.OpenRecordset("SELECT * FROM [" & t & "]")

Позже пропала. Не смог понять её причину, т.к. если она пропала благодаря каким-то изменениям в коде, то изменения были крайне несущественными (во всяком случае на мой взгляд). Ошибка же приведённая выше актуальна до сих пор.
Прошу помощи.

Код процедуры экспорта:
Код

Public Sub MultiExp(tblName)
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim app As Object
Dim wrk As Object
Dim i As Integer
Dim t
Dim j As Integer

' tblName = Me![Поле0]
t = tblName(i)

Set db = CurrentDb
Set app = CreateObject("Excel.Application")
Set wrk = app.Workbooks.Add
Set rst = db.OpenRecordset("SELECT * FROM [" & t & "]")
   For i = 0 To UBound(tblName)
      If i <= wrk.Sheets.Count - 1 Then
      wrk.Sheets(i + 1).Name = t
      Else
      wrk.Sheets.Add(, wrk.Sheets(i)).Name = t
      End If
   app.Sheets(t).Activate
   app.Range("A2").CopyFromRecordset rst
         For j = 1 To rst.Fields.Count
         wrk.Sheets(t).Cells(1, j) = rst(j - 1).Name
         Next j
   Next i
   
   app.Visible = True
   rst.Close: Set rst = Nothing
End Sub

Код кнопки на форме:
Код

Private Sub Кнопка8_Click()
Dim tblName()
Dim cnt As Integer
Dim i As Integer

cnt = Me!Список2.ListCount - 1
 
   If Me!Список2.ListCount = 0 Then
   MsgBox "blablabla"
   Exit Sub
   End If
   
ReDim tblName(0 To cnt)
   
   For i = 0 To cnt
   tblName(i) = Me.Список2.ItemData(i)
   Next i
   
MultiExp tblName
End Sub


P.S. Заранее извиняюсь за возможное несоответствие разделу форума.

Автор: Akina 3.7.2017, 13:00
Так проблема-то в чём? 90% текста для описания проблемы - не нужно, а выискивать, что не так, в красочном описании процесса - лениво...

Автор: Ethex 3.7.2017, 15:22
Akina, в чём проблема.
При попытке экспорта нескольких таблиц в книгу Excell процедура не проходит. Выдаёт ошибку: ошибка 1004: Нельзя присвоить листу имя, совпадающее с именем другого листа, библиотеки объектов или книги, на которую ссылается Visual Basic" в строке кода:
Код

wrk.Sheets(i + 1).Name = t

Сам код представлен в сообщении выше.
Если же в список выбрано одно имя таблицы, экспорт проходит. Но, собственно, всё затевалось для того, чтобы таблиц импортировать можно было более одной

Автор: Akina 3.7.2017, 15:35
Цитата(Ethex @  3.7.2017,  16:22 Найти цитируемый пост)
При попытке экспорта нескольких таблиц в книгу Excell процедура не проходит.

Загрузил и распаковал БД (ту, где три таблицы и одна форма).
В каждую таблицу добавил содержательное поле (имя val, тип текстовое) и по 2 записи.
Открыл форму и нажал кнопку.
Код выполнился без ошибок, данные скопированы в книгу Excel.

Резюме: проблема не воспроизводится.

Добавлено через 6 минут и 50 секунд
PS. Возможный источник проблемы, которая не воспроизведётся на другом инстансе ОС и/или Офиса - локальный шаблон новой книги. Попробуйте после Set wrk = app.Workbooks.Add удалить из книги все листы, кроме одного.

Автор: Ethex 3.7.2017, 16:40
Цитата(Akina @  3.7.2017,  15:35 Найти цитируемый пост)
Попробуйте после Set wrk = app.Workbooks.Add удалить из книги все листы, кроме одного

Агааась. Не работал ранее с такими методами. Пробую разобраться. 

Akina, если вас это не затруднит, посмотрите вторую форму. Если таблиц было три, то вы, скорее всего (если на форме не было списков, то точно) смотрели вариант со статическим массивом (т.е. не мой). И не удивительно что ошибки не возникло. Ошибка при выполнении кода на другом файле (там таблиц шесть).
Цитата(Akina @  3.7.2017,  15:35 Найти цитируемый пост)
В каждую таблицу добавил содержательное поле (имя val, тип текстовое) и по 2 записи.

Необязательно было утруждаться. После экспорта пустой таблицы в первой строке листа появятся имя полей и имя листа изменится. 

Если же затруднит, буду признателен если вы об этом сообщите, чтобы не ожидал у моря погоды.
Спасибо.

P.S. Больше не буду прикреплять больше файлов, чем необходимо  

Автор: Akina 4.7.2017, 08:17
Цитата(Ethex @  3.7.2017,  17:40 Найти цитируемый пост)
Ошибка при выполнении кода на другом файле

Ну там ошибка очевидная. 

Вы открываете рекордсет на первую таблицу ДО цикла, и потом в цикле на все листы будете класть данные из него (Вы же не переоткрываете рекордсет на очередную таблицу списка...). И точно так же не изменяете значение переменной t, в которой храните имя таблицы, используемое как имя листа - само собой при втором проходе Вы пытаетесь вставить лист с тем же именем (t не изменилось же) ещё раз - что собственно и приводит к выводу сообщения.

Очень странно, что Вы этого не увидели при трассировке кода.

Автор: Ethex 4.7.2017, 10:17
Цитата(Akina @  4.7.2017,  08:17 Найти цитируемый пост)
Очень странно

Увы, на данном этапе не очень...

Исчерпывающий ответ. Проблема решена.
Спасибо

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)