MyTetra Share
Делитесь знаниями!
MS Excel - Альтернативный метод экспорта данных
16.03.2019
23:43
Раздел: !Закладки - VBA - Access - msa.polarcom.ru - 11 Импорт - Экспорт

MS Excel - Альтернативный метод экспорта данных

Автор: Кривцов Анатолий

Метод заключается в создании(изменении) рабочей книги при помощи библиотеки объектов Excel. Те, кто знает предмет, или кого устраивает вид рабочего листа при экспорте отчета с группировками - могут дальше не читать.

Преимущества:
    Можно получить полностью оформленный документ;  
    Можно внести данные из разных источников на отдельные листы и даже на один лист рабочей книги;
    Можно обновить данные в существующем файле в тех клетках, где они были внесены ранее.

ОБЯЗАТЕЛЬНО! должна быть установлена ссылка на Microsoft Excel X.X Object Library.
Желательно проверять корректность ссылки перед запуском процедуры. (Или обьявляйте все обьекты Excel As Object - пойдёт)

      Приводится два примера. Оба рабочие и могут быть использованы за основу Ваших примочек.
Первый пример демонстрирует использование основных объектов, свойств и методов библиотеки Excel. В новом файле создается и форматируется простая табличка с формулами

Первый Пример:

Sub TestExcel_1()


On Error GoTo TestExcel_1_err

'Создается новый экземпляр Excel.

Dim ExlDb As New Excel.Application

'Объекты Excel: Workbook - рабочая книга, Worksheet - рабочий

'лист, Range - любой диапазон клеток.

Dim WrkBk As Workbook, WrkSht As Worksheet, _

rngActive As Range, rngInput As Range


' Окно Excel становится видимым. Вставлено в начало процедуры

'для отладки. В отлаженной процедуре лучше перенести в конец.

ExlDb.Visible = True

'Создается новая рабочая книга.

Set WrkBk = ExlDb.Workbooks.Add

'Устанавливается ссылка на активный рабочий лист

Set WrkSht = WrkBk.ActiveSheet

'Устанавливается ссылка на клетку А1 и передается фокус.

Set rngActive = WrkSht.Cells(1, 1)

rngActive.Activate


'В А1 вносится заголовок, меняется размер и толщина шрифта.

'Затем выполняется объединение клеток А1:D4, выравнивание

'по центру(по вертикали и горизонтали) и увеличение высоты

'строки в 2 раза.

rngActive = "Остатки товара на складе."

rngActive.Font.Size = 12

rngActive.Font.Bold = True


With WrkSht.Range(rngActive, rngActive.Offset(0, 3))

.Merge

.HorizontalAlignment = xlHAlignCenter

.VerticalAlignment = xlVAlignCenter

.RowHeight = .RowHeight * 2

End With

'rngActive перемещается на А2 и выполняется оформление шапки.

Set rngActive = rngActive.Offset(1)

With rngActive

.Value = "Наименование товара"

.Offset(0, 1) = "Кол-во"

.Offset(0, 2) = "Цена"

.Offset(0, 3) = "Сумма"

End With


With WrkSht.Range(rngActive, rngActive.Offset(0, 3))

.Borders.LineStyle = xlContinuous 'Разлиновка

.HorizontalAlignment = xlHAlignCenter

.Interior.Color = RGB(220, 220, 220) 'Серый цвет

' Примечание: Хотя функция RGB принимает значения параметров

'в интервале 0-255, клетка принимает в качестве фона комбинацию

'из 0(нет цвета),255(максимальная яркость),220(полутон).

'Может быть есть и другие варианты, но я не нашел.

.Font.Bold = True

End With


'rngActive перемещается на А3 и создается ссылка на область данных (A3:D4).


Set rngActive = rngActive.Offset(1)

Set rngInput = WrkSht.Range(rngActive, rngActive.Offset(0, 3))


'Далее вносятся данные в две строки. Здесь, конечно, просится

'цикл обработки записей в Recordset.


With rngActive

.Value = "Шило"

.Offset(0, 1) = "100"

.Offset(0, 2) = "5"

End With


Set rngActive = rngActive.Offset(1)

With rngActive

.Value = "Мыло"

.Offset(0, 1) = "200"

.Offset(0, 2) = "10"

End With


'По завершении ввода rngActive указывает на последнюю строку

'с данными. Количество строк в диапазоне rngInput изменяется

'(rngActive.row-посленяя строка, rngInput.row-первая строка)

'В данном случае - A3:D4.

Set rngInput = rngInput.Resize(rngActive.row - _

rngInput.row + 1)

'rngActive - 4-й столбец в первой строке rngInput(D3).

Set rngActive = WrkSht.Cells(rngInput.row, 4)

With rngActive

'В клетку D3 Создается формула "=B3*C3"

.Formula = _

"=" & .Offset(0, -2).Address(False, False) & "*" _

& .Offset(0, -1).Address(False, False)

'Формула(и формат) копируется во все клетки 4-го столбца,

'входящие в rngInput(D3:D4).

.Copy rngInput.Columns(4)

'Примечание: Если нужно скопировать только формулу - нужно

'применить следующую конструкцию:

' .Copy - копирование в буфер.

' rngInput.Columns(4).PasteSpecial (xlPasteFormulas)

End With


'Последняя строка подчеркивается сплошной жирной линией.

With rngInput

.Borders.LineStyle = xlContinuous

.Borders(xlEdgeBottom).wEight = xlThick

End With


'rngActive - 3-й столбец в первой пустой строке(C5).

'Свойство UsedRange указывает на диапазон с А1 по правую-нижнюю

'занятую клетку.

'Примечание: Здесь есть хитрость. Подчеркивание жирной линией

'добавляет в UsedRange и следующую строку. В обычном случае

'номер пустой строки определяется как "UsedRange.Rows.Count+1".


With WrkSht

Set rngActive = .Cells(.UsedRange.Rows.Count, 3)

End With


'В C5 вносится "Всего:" и выравнивается вправо.

rngActive = "Всего:"

rngActive.HorizontalAlignment = xlHAlignRight

rngActive.Font.Bold = True


'В D5 вносится формула "=SUM(D3:D4)"

Set rngActive = rngActive.Offset(0, 1)

rngActive.Formula = "=sum(" _

& rngInput.Columns(4).Address(False, False) & ")"

rngActive.Font.Bold = True


'Столбцам C и D присваивается числовой формат и устанавливается

'"Автоширина" столбцов A-D.

With WrkSht

.Columns(1).AutoFit

.Columns(2).AutoFit

.Columns(3).NumberFormat = "#,##0.00"

.Columns(3).AutoFit

.Columns(4).NumberFormat = "#,##0.00"

.Columns(4).AutoFit

End With


' ExlDb.Visible = True


TestExcel_1_exit:

On Error Resume Next

Set rngInput = Nothing

Set rngActive = Nothing

Set WrkSht = Nothing

Set WrkBk = Nothing

Set ExlDb = Nothing


Exit Sub


TestExcel_1_err:

MsgBox Err & " - " & Err.Description, vbCritical

Resume TestExcel_1_exit

End Sub





Второй пример:


'Второй пример демонстрирует обновление данных в существующем

'файле. Комментарии даются только свойствам и методам, не описанным выше.


Sub TestExcel_2()

On Error GoTo TestExcel_2_err

Dim ExlDb As New Excel.Application

Dim WrkBk As Workbook, WrkSht As Worksheet, _

rngActive As Range, rngFind As Range, rngNew As Range

Dim boolIsNewBook As Boolean, boolIsSheetName As Boolean


Const strSheetName = "DataAccess"

Const strPathFile = "C:\TestExcel_2.xls"


'Открывает окно Exсel в виде иконки.

ExlDb.WindowState = xlMinimized

ExlDb.Visible = True


If strPathFile = "" Or Dir$(strPathFile) = "" Then

'Если файл не найден - формируется новая рабочая книга.

'Активному листу присваивается имя из strSheetName.

'Устанавливается флажок boolIsNewBook.

Set WrkBk = ExlDb.Workbooks.Add

Set WrkSht = WrkBk.ActiveSheet

WrkSht.Name = strSheetName

boolIsNewBook = True

Else

'Если файл найден - загружается в Excel.

Set WrkBk = ExlDb.Workbooks.Open(strPathFile)

'Выполняется поиск листа с указанным именем.

'Если найден - становится активным и устанавливается

'флажок boolIsSheetName.

For Each WrkSht In WrkBk.Worksheets

If WrkSht.Name Like strSheetName Then

boolIsSheetName = True

WrkSht.Activate

Exit For

End If

Next WrkSht


If Not boolIsSheetName Then

MsgBox " В файле " & strPathFile & " отсутствует лист" _

& " с именем " & Chr(34) & strSheetName & Chr(34) _

& ", на которую вносятся данные для отчета.@@" _

& " Процедура прервана!", vbCritical

GoTo TestExcel_2_exit

End If

End If


With WrkSht

If boolIsNewBook Then

Set rngActive = .Cells(1, 1) 'A1

rngActive = "ID"

rngActive.Offset(0, 1) = "Наименование"

rngActive.Offset(0, 2) = "Сумма"

End If


Set rngActive = .Cells(2, 1) 'A2

rngActive.Offset(0, 2).Activate 'Фокус на C2


If Not boolIsNewBook And .UsedRange.Rows.Count >= 2 Then

'rngNew - клетка во второй пустой строке и 1-м столбце.

'Используется для добавления новых записей.

Set rngNew = .Cells(.UsedRange.row + _

.UsedRange.Rows.Count + 1, 1)

'rngFind - диапазон для поиска идентификатора записи.

'Указывает на клетки 1-го столбца со 2-й по последнюю занятую

'строку на листе.

Set rngFind = .Range(rngActive, rngNew.Offset(-2, 0))

'Очищаются все клетки с B2 по правую нижнюю занятую клетку.

.Range(.Cells(2, 2), rngNew.Offset(0, .UsedRange.Column + _

.UsedRange.Columns.Count - 1)).Clear

Else

'Если новый файл - rngNew указывает на A2

Set rngNew = rngActive

Set rngFind = Nothing

End If

End With


Set rngActive = Nothing


'Обрабатываются два произвольных варианта. Реально здесь должен

'быть Recordset и вместо констант ID1,ID2 указывается значение

'ключевого поля.

'Для контроля работы процедуры можно поменять значения констант

'местами, а затем изменить значение ID1 на 3.

Const ID1 = 1

Const ID2 = 2


'Если ссылка на rngFind установлена - выполняется поиск значения.

If Not rngFind Is Nothing Then

Set rngActive = rngFind.Find(ID1, , xlValues, _

xlWhole, xlByRows, xlNext)

End If


If rngActive Is Nothing Then

'Если значение НЕ найдено, то ввод будет выполняться в строку,

'на которую указывает rngNew, а затем rngNew перемещается

'на строку ниже.

With rngNew

.Value = ID1

.Offset(0, 1) = "Шило"

.Offset(0, 2) = "100"

End With

Set rngNew = rngNew.Offset(1, 0)


Else

'Если значение найдено (rngInput указывает на найденную клетку),

'ввод выполняется в эту строку.

With rngActive

.Offset(0, 1) = "Шило"

.Offset(0, 2) = "100"

End With

Set rngActive = Nothing

End If

'-------- Второй вариант. Только для примера. --------------

If Not rngFind Is Nothing Then

Set rngActive = rngFind.Find(ID2, , xlValues, _

xlWhole, xlByRows, xlNext)

End If


If rngActive Is Nothing Then

With rngNew

.Value = ID2

.Offset(0, 1) = "Мыло"

.Offset(0, 2) = "200"

End With

Set rngNew = rngNew.Offset(1, 0)

Else

With rngActive

.Offset(0, 1) = "Мыло"

.Offset(0, 2) = "200"

End With

Set rngActive = Nothing

End If

'-----------------------------------------------------------


'Разворачивание окна Excel

ExlDb.WindowState = xlMaximized

'Сохранение файла на диске.

WrkBk.SaveAs strPathFile


TestExcel_2_exit:

On Error Resume Next

Set rngFind = Nothing

Set rngNew = Nothing

Set rngActive = Nothing

Set WrkSht = Nothing

Set WrkBk = Nothing

Set ExlDb = Nothing


Exit Sub


TestExcel_2_err:

Select Case Err

Case 1004 'Отказ от сохранения

Case Else

MsgBox Err & " - " & Err.Description, vbCritical

End Select

Resume TestExcel_2_exit

End Sub




Так же в этом разделе:
 
MyTetra Share v.0.52
Яндекс индекс цитирования