Связать таблицы excel vba

Содержание

  1. Vba excel объединение таблиц
  2. Слияние двух таблиц Excel (с использованием VBA)
  3. Редактировать:
  4. Vba excel объединение таблиц

Vba excel объединение таблиц

Существует две таблицы с данными:

  • Таблица Goods в которой хранятся товары.
  • Таблица Costs в которой хранятся цены этих товаров.

Нужно связать эти две таблицы в одну, получив, тем самым таблицу, содержащую в себе как товары, так и их цены (разбиты по городам). В обеих таблица существует поле «Номенклатурный номер», по которому и предполагается связывать данные из исходных таблиц. Проще говоря, нужно получить таблицу Result, добавив в таблицу Goods последние четыре столбца из таблицы Costs, на основании эквивалентности поля «Номенклатурного номер».

Excel 2003
Файл с книгой прикрепил.

Вложения

Catalog.rar (352.6 Кб, 63 просмотров)

У Вас там косяк в номере 400019075.
Если последние 4, то отработал код из http://hugo.nxt.ru/CompareFiles.Find.rar
1146 совпадений.

Настройки:
Файл — приёмник: C:tempVectorCКаталог.xls
Файл — источник: C:tempVectorCКаталог.xls
Столбцы сравнения в приёмнике: a
Столбцы сравнения в источнике: a
Лист — приёмник (№): 1
Лист — источник (№): 2
Столбцы — приёмники данных копирования: O,P,Q,R
Столбцы — источники данных копирования: E,F,G,H

Добиваем первый лист данными второго. Можно сперва на лист Result скопировать данные первого листа и добивать туда.

Спасибо, только у меня почему-то ничего не получилось.
Пишет:

Object doesn’t support this property or method

В чём косяк номера 400019075?

Жаль. Версия Экселя какая у Вас? У меня на 2000 и 2007 работает.
А косяк в том, что 400019075 два раза в таблице — один раз данных больше.

Хотя именно под эту задачу несложно макрос на массиве написать — вечером могу сделать, если раньше не напишут.

Источник

Слияние двух таблиц Excel (с использованием VBA)

Я пытался выяснить, как объединить две таблицы из одной книги в третью, используя VBA. Пример:

Отключенный выход (рабочий лист3):

Мне понадобится решение VBA, так как исходные таблицы занимают около 400 строк, и мне нужно будет выполнить одну и ту же операцию для нескольких книг. Я был бы очень признателен за любое предложение по этой проблеме!

Редактировать:

Если это кому-то интересно, мне удалось создать рабочий код. Worksheet1 был псевдонимом для «Импорт списка», а Worksheet2 — «Экспорт списка». В обоих листах я вставил столбец (C), в котором указаны обе страны. Я использовал этот новый столбец и значения для построения таблицы в Worksheet3 (теперь «Combolist»).

Хотя это можно решить с помощью VBA, вам, вероятно, будет лучше использовать формулы (если вы не должны делать это очень часто). Решение VBA потребует некоторых ноу-хау и даже больше, если вы хотите иметь возможность поддерживать решение.

Формула Excel будет довольно простой. Сначала создайте столбец UniqueID :

Вы бы сделали то же самое для обеих таблиц. Затем получите все уникальные уникальные UniqueID . Для этого вы можете использовать Data > Remove Duplicates , просто сделайте копию перед удалением дубликатов, иначе вы удалите записи из вашего источника. Поместите этот список UniqueID в новую Table . Имейте в виду, что все это будет проще, если все ваши данные находятся в формате Table (вы увидите вкладку » Table » в ленте, когда внутри диапазона таблицы.

Если вам нужно отформатировать данные в виде таблицы, перейдите на рабочий лист, нажмите CTRL+HOME (это относится к самой первой ячейке). Если ваша первая ячейка находится в другом месте, просто перейдите туда. Если ваша таблица является единственной информацией на листе, попробуйте использовать CTRL+SHIFT+END чтобы выделить ее для последней используемой ячейки. В противном случае комбинация CTRL+SHIFT+RIGHT и CTRL+SHIFT+DOWN доставит вам то, что вам нужно. Наконец, назовите свой стол для любви ко всему, что превосходит, эта простая привычка экономит массу времени. В моем примере я предполагаю, что у вас есть таблица » Primary и Secondary .

Наша формула в нашей комбинированной таблице будет выглядеть примерно так:

=IfError(Vlookup([UniqueID], Primary, Column(Primary[Value]), False), «»)

Или, если ваша Primary таблица не начинается в первом столбце, используйте это:

=IfError(Vlookup([UniqueID], Primary, 4, False), «»)

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

Сделайте то же самое в следующем столбце для другой таблицы:

=IfError(Vlookup([UniqueID], Secondary, Column(Primary[Value]), False), «»)

=IfError(Vlookup([UniqueID], Secondary, 4, False), «»)

Это «объединит» два набора на основе общего UniqueID и оставит пробелы, если запись не существует. Изучение того, как это сделать, может быть менее удобным, чем изучение того, как это сделать в VBA, но я бы сильно отговорил вас от изучения VBA, если вы не можете использовать такую реализацию.

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

Источник

Vba excel объединение таблиц

Модератор форума: _Boroda_, китин

Мир MS Excel » Вопросы и решения » Excel и другие приложения » Google Docs » Скрипт объединения нескольких таблиц в одну (Формулы/Formulas)

Скрипт объединения нескольких таблиц в одну

Kashimirush Дата: Четверг, 27.02.2020, 15:50 | Сообщение № 1

function supercopy2() <
var app = SpreadsheetApp;
//Указываем ID целевой страницы
var SheetID = ‘Ваш АЙДИ’;
//Задаем начальную строку массива (это заголовок из целевой таблицы)
var DataAll = app.openById(SheetID).getSheetByName(‘Реестр’).getRange(1, 1, 1, 4).getValues();
//Перечисляем мини реестры:
var arrID = [‘Ваш АЙДИ1’,
‘Ваш АЙДИ2’,
‘Ваш АЙДИ3’]
var i = 1;

//Запускаем цикл
while (i

function supercopy2() <
var app = SpreadsheetApp;
//Указываем ID целевой страницы
var SheetID = ‘Ваш АЙДИ’;
//Задаем начальную строку массива (это заголовок из целевой таблицы)
var DataAll = app.openById(SheetID).getSheetByName(‘Реестр’).getRange(1, 1, 1, 4).getValues();
//Перечисляем мини реестры:
var arrID = [‘Ваш АЙДИ1’,
‘Ваш АЙДИ2’,
‘Ваш АЙДИ3’]
var i = 1;

Ответить

function supercopy2() <
var app = SpreadsheetApp;
//Указываем ID целевой страницы
var SheetID = ‘Ваш АЙДИ’;
//Задаем начальную строку массива (это заголовок из целевой таблицы)
var DataAll = app.openById(SheetID).getSheetByName(‘Реестр’).getRange(1, 1, 1, 4).getValues();
//Перечисляем мини реестры:
var arrID = [‘Ваш АЙДИ1’,
‘Ваш АЙДИ2’,
‘Ваш АЙДИ3’]
var i = 1;

//Запускаем цикл
while (i Автор — Kashimirush
Дата добавления — 27.02.2020 в 15:50

Gustav Дата: Четверг, 27.02.2020, 18:13 | Сообщение № 2

ИМХО (ниже всё ИМХО — можно слушать меня, а можно и нет), излишне, ничего не экономится, а с толку при чтении кода сбивает

«.toString()» тут излишне, здесь строка и так «сложится» с числом как надо (как с & в VBA)

Переменная ss практически устойчиво в листингах GAS обозначает объект (s)pread(s)heet. Использовать ss для range — как-то совсем не комильфо (даже ни одной буквы не совпадает). Для диапазона лучше range или rng, для листа — sheet или sht. Помните о потенциальных читателях Вашего кода!

ИМХО (ниже всё ИМХО — можно слушать меня, а можно и нет), излишне, ничего не экономится, а с толку при чтении кода сбивает

«.toString()» тут излишне, здесь строка и так «сложится» с числом как надо (как с & в VBA)

Переменная ss практически устойчиво в листингах GAS обозначает объект (s)pread(s)heet. Использовать ss для range — как-то совсем не комильфо (даже ни одной буквы не совпадает). Для диапазона лучше range или rng, для листа — sheet или sht. Помните о потенциальных читателях Вашего кода! Gustav

ИМХО (ниже всё ИМХО — можно слушать меня, а можно и нет), излишне, ничего не экономится, а с толку при чтении кода сбивает

«.toString()» тут излишне, здесь строка и так «сложится» с числом как надо (как с & в VBA)

Переменная ss практически устойчиво в листингах GAS обозначает объект (s)pread(s)heet. Использовать ss для range — как-то совсем не комильфо (даже ни одной буквы не совпадает). Для диапазона лучше range или rng, для листа — sheet или sht. Помните о потенциальных читателях Вашего кода! Автор — Gustav
Дата добавления — 27.02.2020 в 18:13

anvg Дата: Четверг, 27.02.2020, 21:33 | Сообщение № 3
Kashimirush Дата: Пятница, 28.02.2020, 07:52 | Сообщение № 4
Работа, работа, перейди на Федота.

Ответить

Kashimirush Дата: Пятница, 28.02.2020, 07:55 | Сообщение № 5
Работа, работа, перейди на Федота.

Ответить

Kashimirush Дата: Пятница, 28.02.2020, 07:56 | Сообщение № 6
Работа, работа, перейди на Федота.

Ответить

Kashimirush Дата: Пятница, 28.02.2020, 08:59 | Сообщение № 7
Работа, работа, перейди на Федота.

Ответить

anvg Дата: Пятница, 28.02.2020, 11:09 | Сообщение № 8

разница в подходах: процедурный для for, while и функциональный для forEach, map, filter, reduce и т. д.. По большому счёту — дело вкуса.

разница в подходах: процедурный для for, while и функциональный для forEach, map, filter, reduce и т. д.. По большому счёту — дело вкуса.

разница в подходах: процедурный для for, while и функциональный для forEach, map, filter, reduce и т. д.. По большому счёту — дело вкуса.

Kashimirush Дата: Понедельник, 02.03.2020, 15:29 | Сообщение № 9

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

Вопрос по форматированию задал, потому что время как то не правильно переходило на 26 минут меньше), оказалось таблицы просто в разных часовых поясах были.

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

Вопрос по форматированию задал, потому что время как то не правильно переходило на 26 минут меньше), оказалось таблицы просто в разных часовых поясах были. Kashimirush

Работа, работа, перейди на Федота.

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

Вопрос по форматированию задал, потому что время как то не правильно переходило на 26 минут меньше), оказалось таблицы просто в разных часовых поясах были. Автор — Kashimirush
Дата добавления — 02.03.2020 в 15:29

Источник

Adblock
detector

 

Jack Famous

Пользователь

Сообщений: 10852
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

#1

17.11.2016 21:59:29

Доброго вечера, уважаемые форумчане!
Прошу вашей помощи в организации связи «один-ко-многим» между двумя таблицами через макрос. От создания сводных по нескольким таблицам (это также решило бы проблему) пока отказался, ввиду слабого знания материала и опасений «накосячить», а макрос есть макрос — из созданной им таблицы я всегда смогу отличную сводную построить.
Не воспринимайте, пожалуйста, как ТЗ — выложил все мысли по теме, может чем-то поможет…

В посте №24 — рабочий макрос.

Пример такой (описание файла-примера):

Детали по макросу (как примерно я это вижу):

Комментарии:

Примеры похожих проблем:

Инструкция по использованию спойлеров на форуме

Прикрепленные файлы

  • Сложное объединение таблиц.xlsx (15.43 КБ)

Изменено: Jack Famous24.11.2016 09:31:50

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

SuperCat

Пользователь

Сообщений: 2737
Регистрация: 21.12.2012

Опять ТЗ строчим?

There is no knowledge that is not power

 

Jack Famous

Пользователь

Сообщений: 10852
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

#3

17.11.2016 22:47:53

SuperCat, так и знал)))) да вот как ни напишу — всё как ТЗ выглядит))))

Вот то, что смог по теме в VBA)))

Изменено: Jack Famous18.11.2016 00:10:27

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

С.М.

Пользователь

Сообщений: 936
Регистрация: 22.12.2012

#4

18.11.2016 02:51:45

Тренировка скрывания под спойлер

Изменено: С.М.18.11.2016 02:55:06

 

Jack Famous

Пользователь

Сообщений: 10852
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

С.М., наконец-то первый вариант по теме))))) спасибо вам большое — как обращаться с этим зверем?))) выделял и 1 и 2 таблицу, запускал макрос — ничего(((

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

Андрей VG

Пользователь

Сообщений: 11878
Регистрация: 22.12.2012

Excel 2016, 365

#6

18.11.2016 12:11:34

Доброе время суток

Цитата
Сложное объединение двух таблиц.

Несколько щелчков мышкой… в Power Query. И выясняется, что в результате есть ошибочка :)
Успехов.

Прикрепленные файлы

  • Копия Копия Сложное объединение таблиц.xlsx (26.85 КБ)

Изменено: Андрей VG18.11.2016 12:12:23
(Файл не той системы приложил.)

 

Jack Famous

Пользователь

Сообщений: 10852
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

Андрей VG, здравствуйте!))) спасибо за пример, но пишет «указанного файла не существует»
По поводу Power Query — знаю, что так можно, но пока что боюсь DAX-формул (писал в шапке темы). Жду уроков от Николая Павлова…

Изменено: Jack Famous18.11.2016 12:15:52

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

Андрей VG

Пользователь

Сообщений: 11878
Регистрация: 22.12.2012

Excel 2016, 365

#8

18.11.2016 12:15:38

Цитата
Jack Famous написал:
«указанного файла не существует»

Вы слишком быстро пришли за примером. Обнаружил, что не ту версию файла прикрепил. Переложил, и тут вы — качать… Накладка, однако :)

 

Jack Famous

Пользователь

Сообщений: 10852
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

Андрей VG, спасибо большое)))) есть возможность рассказать, как эту динамическую связку организовывать? Я бы в динамике всё построил…

Изменено: Jack Famous18.11.2016 12:19:51

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

JeyCi

Пользователь

Сообщений: 3357
Регистрация: 27.11.2013

#10

18.11.2016 12:29:23

Цитата
Jack Famous написал: По поводу Power Query — знаю, что так можно, но пока что боюсь DAX-формул

не делайте непроверенных выводов!.. в PQ — язык другой (M-language), язык DAX в PP
p.s. см.  

#14 —> Расширенный редактор

Изменено: JeyCi18.11.2016 12:32:33

чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок — обратитесь к собеседнику на ВЫ — ответ на ваш вопрос получите — а остальное вас не касается (п.п.п. на форумах)

 

Максим Зеленский

Пользователь

Сообщений: 4646
Регистрация: 11.06.2014

Microsoft MVP

#11

18.11.2016 12:31:51

Можно чуть подсократить:

Код
let
    Источник = Excel.CurrentWorkbook(){[Name="помещения"]}[Content],
    #"Объединенные запросы" = Table.NestedJoin(Источник,{"№ типа"},типы,{"№ типа"},"NewColumn",JoinKind.LeftOuter),
    #"Развернутый элемент NewColumn" = Table.ExpandTableColumn(#"Объединенные запросы", "NewColumn", {"Формула"}, {"Формула"}),
    #"Сортированные строки" = Table.Sort(#"Развернутый элемент NewColumn",{{"№ пом.", Order.Ascending}, {"Формула", Order.Ascending}}),
    #"Переименованные столбцы1" = Table.RenameColumns(#"Сортированные строки",{{"Формула", "Материал"}}),
    #"Changed Type" = Table.TransformColumnTypes(#"Переименованные столбцы1",{{"№ пом.", Int64.Type}, {"№ типа", Int64.Type}})
in
    #"Changed Type"

F1 творит чудеса

 

Андрей VG

Пользователь

Сообщений: 11878
Регистрация: 22.12.2012

Excel 2016, 365

#12

18.11.2016 13:05:09

Цитата
Максим Зеленский написал: Можно чуть подсократить:

Конечно!

Код
let
    types = Excel.CurrentWorkbook(){[Name="типы"]}[Content],
    houses = Excel.CurrentWorkbook(){[Name="помещения"]}[Content],
    renHouses = Table.RenameColumns(houses, { {"№ типа", "typeName"} }),
    joined = Table.Join(renHouses, {"typeName"}, types, {"№ типа"})[[#"№ пом."], [#"№ типа"], [Формула]]
in
    Table.RenameColumns(joined, { {"Формула", "Материал"} })
 

С.М.

Пользователь

Сообщений: 936
Регистрация: 22.12.2012

#13

18.11.2016 13:27:25

Цитата
Jack Famous написал #5:
С.М. , как обращаться с этим зверем?))) выделял и 1 и 2 таблицу, запускал макрос — ничего(((

Не надо ничего выделять, жмём кнопку :

Прикрепленные файлы

  • Сложное объединение таблиц.1.xlsb (27 КБ)

 

Jack Famous

Пользователь

Сообщений: 10852
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

С.М., огромное спасибо!!! Буду разбираться с кодом)))
если можно закомментируйте, пожалуйста код — хочу понять, какие переменные участвуют, чтобы запихнуть их в диалоговые окна при запуске макроса…
JeyCi, благодарю за подсказку и коррекцию)))

Андрей VG

и

Максим Зеленский

, благодарою за вариант решения через PQ — в перспективе этот вариант, скорее всего станет основным, а пока буду учить матчасть))))

Изменено: Jack Famous18.11.2016 13:45:07

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

Максим Зеленский

Пользователь

Сообщений: 4646
Регистрация: 11.06.2014

Microsoft MVP

#15

18.11.2016 15:11:30

Андрей VG, нет предела совершенству  :D

Скрытый текст

Изменено: Максим Зеленский18.11.2016 15:12:10

F1 творит чудеса

 

Андрей VG

Пользователь

Сообщений: 11878
Регистрация: 22.12.2012

Excel 2016, 365

#16

18.11.2016 15:33:34

Максим, у меня PQL через раз ругается, что не может выполнить Join из-за одинаковых названий столбцов

Код
Table.Join(houses, {"№ типа"}, types, {"№ типа"})

, поэтому и пришлось делать «лишнюю» операцию. Причём, если соединение по двум и более столбцам, тогда без вопросов — отрабатывает как и должно быть. Один из глюков PQL — может в последних и поправили.

 

странно, у меня не ругается…

 

Максим Зеленский

Пользователь

Сообщений: 4646
Регистрация: 11.06.2014

Microsoft MVP

#18

18.11.2016 16:46:01

я думаю, в этом дело:

Цитата
An Expression.Error is thrown if a column with the same name to appear in both tables of the join unless the column is selected by both key1 and key2 and the join is an inner join.

F1 творит чудеса

 

Jack Famous

Пользователь

Сообщений: 10852
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

Максим Зеленский, Андрей VG, подскажите, а эти формулы только руками вбивать или есть что-то вроде мастера функций, как в Excel — тогда дело за синтаксисом и практикой))

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

JeyCi

Пользователь

Сообщений: 3357
Регистрация: 27.11.2013

#20

18.11.2016 18:24:47

Цитата
Jack Famous написал: а эти формулы только руками вбивать или

Jack Famous

вы кнопки в надстройке нажимайте и смотрите, что получается, а в расширенном редакторе — весь код целиком увидеть можно… вопрос в том в какой последовательности какие кнопки (в зависимости от того, какие шаги по коду совершить хотите)… последовательность — это уже вопрос алгоритмизации… для получения нужного на выходе… вы не стесняйтесь знакомиться с надстройкой  ;) , если чётко себе представляете алгоритм, который вам надо закодировать [решение порождает человек, простые шаги может пройти по кнопкам на ленте PQ]… сложные моменты придётся править руками, когда захотите выполнять ювелирную работу (как с макрорекодером) — что вызвало проблему, чтобы самому прийти к такому выводу??особенно после прохождения по моему линку в #10 и ответа Максима там…

Изменено: JeyCi18.11.2016 18:30:27

чтобы не гадать на кофейной гуще, кто вам отвечает и после этого не совершать кучу ошибок — обратитесь к собеседнику на ВЫ — ответ на ваш вопрос получите — а остальное вас не касается (п.п.п. на форумах)

 

С.М.

Пользователь

Сообщений: 936
Регистрация: 22.12.2012

#21

18.11.2016 20:05:07

Цитата
Jack Famous написал:
С.М. , Буду разбираться с кодом)))
если можно закомментируйте, пожалуйста код — хочу понять, какие переменные участвуют

Вот:

 

Jack Famous

Пользователь

Сообщений: 10852
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

JeyCi, надо пробовать — спасибо за напутствие!))
С.М., большое спасибо вам!)) Попробую что-нибудь сделать с этим ;)  наверняка куча вопросов будет  :D

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

Jack Famous

Пользователь

Сообщений: 10852
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

С.М., посидел, посмотрел — из переменных, которые смог: разглядеть только типы, помещения и таблица. Первые 2 — в виде именованных диапазонов, а таблица и есть таблица)) не могли бы вы изменить сам принцип работы макроса? Сейчас он решает одну конкретную задачу — ни влево, ни в право, к тому же он вставляет не значения столбца, а самостоятельно индексирует третий столбец справочника. То есть, если мне нужно вставлять какой-либо другой столбец — это очень замороченная процедура получится…
Прошу вас попробовать сделать нечто похожее, как я начал в #3. То есть, выбираем ключевые поля в обоих таблицах через диалоговые окна, выбираем, какой столбец справочника переносить в целевую таблицу (размножением строк) и всё. Номеров типов и слоёв ведь тоже может не быть, поэтому макрос должен считать всё самостоятельно, ориетируясь не на числа, а только на то, сколько строк переносимого столбца справочника соответствуют одному и тому же значению ключа справочника

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

Jack Famous

Пользователь

Сообщений: 10852
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

#24

24.11.2016 09:41:44

Доброго утра, уважаемые форумчане!
Александр С.М. согласился помочь с макросом и вот, что мы получили в итоге (выкладываю файл с макросом и отдельно модуль и класс для замечаний и предложений по оптимизации):

В модуле

В Class1 раздела Class Modules

Инструкция к макросу

Прикрепленные файлы

  • Объединение таблиц.xlsb (24.13 КБ)

Изменено: Jack Famous24.11.2016 10:25:06

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

Jack Famous

Пользователь

Сообщений: 10852
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

Отдельная благодарность Андрей VG, Максим Зеленский и JeyCi — с их подсказок удалось довольно простым способом осуществить подобную связь в динамически обновляемом виде через запросы в Power Query — теперь, связав 2 и более таблицы через запросы по ключевым полям и удалив в этих запросах всё лишнее, можно готовый итоговый запрос выгрузить в книгу и строить сводную по нему. При изменении/дополнении/удалении данных в справочниках — всё динамически обновляется и в сводной.
Теперь я серьёзно настроен на изучение Power BI в целом — спасибо, мастера!  8)

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

Максим Зеленский

Пользователь

Сообщений: 4646
Регистрация: 11.06.2014

Microsoft MVP

#26

29.11.2016 15:40:57

Цитата
Jack Famous написал:
можно готовый итоговый запрос выгрузить в книгу

Можно и не выгружать

F1 творит чудеса

 

Jack Famous

Пользователь

Сообщений: 10852
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

Максим Зеленский, да — добавить в модель данных и готово))) подскажите, пожалуйста аналоги функций СУММЕСЛИМН и СЧЁТЕСЛИМН для Power Query. Или это только через DAX в Power Pivot? А то таблички посвязывал по ключевым полям (6 штук), а этого капец как не хватает…

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

Андрей VG

Пользователь

Сообщений: 11878
Регистрация: 22.12.2012

Excel 2016, 365

#28

29.11.2016 21:21:22

Доброе время суток

Цитата
Jack Famous написал:
аналоги функций СУММЕСЛИМН и СЧЁТЕСЛИМН для Power Query

Смотря что вы под этим подразумеваете. В общем случае — фильтрация по критериям и группировка (плоская сводная таблица).

 

Jack Famous

Пользователь

Сообщений: 10852
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

Андрей VG, доброй ночи!
Вы мне всегда подсказывали по поводу сводных и Power Pivot — надеюсь, что и тут поможете… Прикрепил файл-пример со связкой 3х таблиц через Power Query — как вышло и чего не хватает.
ЖЁЛТЫМ выделены ключевые поля
ЗЕЛЁНЫМ выделены поля с формулами
СИРЕНЕВЫМ выделены пользовательские столбцы с формулами в Power Query
ОРАНЖЕВЫМ выделено то, чего не смог достичь внутри запросов в Power Query

Изменено: Jack Famous30.11.2016 00:24:07

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

Jack Famous

Пользователь

Сообщений: 10852
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

#30

30.11.2016 00:27:28

МОДЕРАТОРАМ: предлагаю (из-за развития темы вне названия) следующее название темы — «Объединение таблиц. Макросы, Power Query и Power Pivot»

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

Это продолжение перевода книги Зак Барресс и Кевин Джонс. Таблицы Excel: Полное руководство для создания, использования и автоматизации списков и таблиц (Excel Tables: A Complete Guide for Creating, Using and Automating Lists and Tables by Zack Barresse and Kevin Jones. Published by: Holy Macro! Books. First printing: July 2014. – 161 p.). Visual Basic for Applications (VBA) – это язык программирования, который можно использовать для расширения стандартных возможностей Excel. VBA позволяет автоматизировать сложные или повторяющиеся задачи. Например, VBA можно использовать для форматирования листа, получаемого ежедневно из внешнего источника, извлечения данных с веб-страницы раз в неделю или построения сложной пользовательской функции листа.

Предыдущая глава        Содержание    Следующая глава

Ris. 9.1. Redaktirovanie makrosov

Рис. 9.1. Редактирование макросов

Скачать заметку в формате Word или pdf

Вот некоторые примеры автоматизации Таблиц Excel:

  • Вы создаете приложение для использования менее опытными пользователями, и хотите заблокировать Таблицу, предоставляя несколько простых функций для добавления, редактирования и удаления записей.
  • Вы хотите предоставить функциональные возможности для редактирования групп записей в пользовательской форме, например, транзакции по одному заказу (аванс, финальная оплата, фрахт, пошлина и т.д.).
  • Ваша Таблица поддерживает другие функции книги, такие как запись информации о событиях в журнал, и вы хотите вставлять строки в таблицу, обновлять существующие табличные данные, а также находить и извлекать строки из Таблицы.
  • Вы хотите провести аудит Таблицы и отобразить ошибки, которые необходимо исправить.

Для работы с этой главой лучше всего, если у вас есть начальный уровень программирования, вы знакомы с объектной моделью и хотите расширить функциональность Таблиц Excel (см. Джон Уокенбах. Excel 2010. Профессиональное программирование на VBA). Среда VBA не русифицирована.

Один из самых простых способов начать работать с VBA – это использовать запись макросов. При этом действия, которые вы совершаете в Excel, записываются в среде VBA в виде инструкций. Не забудьте выключить запись макросов, когда автоматизированные действия будут завершены. Вы можете просматривать и редактировать код VBA, пройдя по меню Разработчик –> Макросы, выбрать имя макроса и нажать кнопку Изменить (рис. 9.1). Код, сгенерированный при записи макросов, не самый эффективный, и вы часто можете улучшить его с помощью редактирования.

Если вкладка Разработчик не видна, включите ее, пройдя по меню Файл –> Параметры –> Настроить ленту, и установив флажок на вкладке Разработчик.

VBA, Excel и объекты

Этот раздел можно пропустить, если у вас уже есть опыт работы с объектами в среде Excel VBA.

В среде VBA приложение Excel представляет объекты, к которым можно получить доступ, в виде объектной модели Excel. Основные объекты Excel:

  • Application – Приложение Excel.
  • Workbooks – коллекция всех книг, открытых в данный момент в приложении Excel. В общем случае коллекция – набор объектов. В этом случае коллекция Workbooks представляет собой набор отдельных объектов Workbook.
  • Workbook – одна книга.
  • Worksheets – коллекция всех листов в рабочей книге.
  • Worksheet – отдельный рабочий лист или вкладка в рабочей книге.
  • Cells – совокупность всех ячеек на листе.
  • Range – набор из одной или нескольких ячеек на одном листе. Клетки могут быть прерывистыми. Любая ссылка даже на одну ячейку является объектом Range.

Объекты имеют свойства. Каждый объект принадлежит родительскому объекту. Например, родителем объекта Workbook является объект Application, а родителем объекта Cell – объект Worksheet. Одним из исключений является объект Application, который не имеет родителя; это объект самого высокого уровня, доступный при просмотре объектной модели Excel. При описании контекста объекта или метода часто используются следующие термины:

  • Parent – родительский объект. Например, родительский объект для Cell – это Worksheet.
  • Member – член родительского объекта. Например, член объекта Worksheet – объект Cell. Член также может быть методом, который выполняет действие.

Когда вы ссылаетесь на объект, вы должны начать с самого высокого уровня. Чтобы найти каждый подчиненный объект, введите родительский объект, за которым следует точка, а затем дочерний элемент. Например, чтобы сослаться на значение ячейки A1 на листе Sheet1 в книге My Workbook.xlsx, используйте следующий синтаксис:

Application.Workbooks(«My Workbook.xlsm»).Worksheets(«Sheet1»).Cells(1,1).Value

Ссылки в VBA как правило используют синтаксис R1C1, а не А1.

Объектная модель Excel предоставляет объекты по умолчанию в зависимости от того, какой элемент приложения в данный момент активен. Например, следующий синтаксис ссылается на ячейку A1 на листе, активном в момент выполнения кода:

Хотя этот синтаксис работает, он не считается хорошей практикой. Мы рекомендуем использовать объект ActiveSheet, если вы действительно намеревались ссылаться на активный лист:

Application.ActiveSheet.Cells(1,1).Value

Единственный объект, который подразумевается во всей среде Excel VBA, – это объект Application, и его можно без проблем опустить. Поэтому следующие ссылки не являются неоднозначными в любом месте среды Excel VBA:

Workbooks(«My Workbook.xlsm»).Worksheets(«Sheet1»).Cells(1,1).Value

ActiveSheet.Cells(1,1).Value

Вы можете назначить ссылку на любой объект переменной, если эта переменная имеет тот же тип, что и объект, или определена как универсальный тип объекта. Основная причина для этого – удобство. Если вы ссылаетесь на объект повторно, то выделение переменной для ссылки на этот объект может привести к уменьшению объема кода, который будет легче читать и поддерживать. Например, вы можете назначить ссылку на Sheet1 переменной:

Dim TargetWorksheet As Worksheet

Set TargetWorksheet = Workbooks(«My Workbook.xlsm»).Worksheets(«Sheet1»)

Теперь ссылка на А1 может быть записана в виде:

TargetWorksheet.Cells(1,1).Value

Ключевое слово Set присваивает ссылку. VBA требует использования ключевого слова Set при назначении ссылок на объекты. Кроме того, переменная является ссылкой на объект, а не копией объекта. Вы можете иметь любое количество переменных, содержащих ссылку на один и тот же экземпляр объекта.

Следует различать объекты, экземпляры объектов и ссылки на объекты. Объект включает в себя объектную модель (свойства и методы, которые ему принадлежат) и код, который управляет его поведением. Примером объекта является Worksheet. Экземпляр объекта является конкретным экземпляром этого объекта и включает в себя данные и значения свойств, связанные с этим экземпляром объекта. Листы Sheet1 и Sheet2 примеры экземпляров объектов. Переменная, ссылающаяся на объект, содержит ссылку на объект.

При определении переменных, ссылающихся на объекты, необходимо определить переменную того же типа, что и объект, на который ссылаются, или присвоить универсальный тип объекта. В общем случае универсальный тип объекта следует использовать только в том случае, если этой переменной будут присвоены ссылки на другие объекты различных типов; при использовании универсального типа объекта редактор VBA не может помочь вам с интеллектуальной подсказкой IntelliSense (IntelliSense представляет список свойств и методов объекта при вводе ссылки на объект, за которой следует точка.)

В дальнейшем описании мы используем следующие объекты:

  • ThisWorkbook – рабочая книга, в которой выполняется код. Это удобно, когда единственная книга, на которую ссылаются, является той, в которой находится код. С этой рабочей книгой работать легче, чем с рабочими книгами (My Workbook.xlsm), особенно когда имя рабочей книги может меняться.
  • Me – когда код находится в модуле кода листа, Me – это удобный способ ссылаться на объект листа, в котором находится код.

Excel Online открывает файлы с VBA (при просмотре в браузере), но не выполняет код. Код игнорируется при открытии книги в приложении Excel Online, но сам код сохраняется.

Объект ListObject

Excel использует объект ListObject для представления таблицы в объектной модели Excel. Он содержится в коллекции ListObjects, которая принадлежит объекту Worksheet. Используйте этот синтаксис для ссылки на Таблицу на листе:

ThisWorkbook.Worksheets(«Sheet1»).ListObjects(«Table1»)

Назовите Таблицу как-то иначе, чем имя по умолчанию. Это поможет вам как при написании кода, так и позже, когда вы смотрите на свой код, пытаясь понять, что вы сделали. Это также будет полезно для других пользователей, которые будут изучать ваш код.

Поскольку ListObjects – это набор таблиц, вы можете получить доступ к конкретной Таблице с помощью индекса:

ThisWorkbook.Worksheets(«Sheet1»).ListObjects(1)

Индекс (или позиция) объекта ListObject в коллекции ListObjects определяется порядком, в котором объекты ListObject были созданы на листе. Объект ListObject может быть назначен переменной, которая была определена как тип ListObject. Объект ListObject имеет ряд свойств и методов, используемых для доступа к таблицам и управления ими.

Свойства объекта Таблица

Пять свойств представляют собой основные части таблицы. Каждое из этих свойств является объектом диапазона Range. Два дополнительных свойства или коллекции предоставляют доступ к строкам и столбцам Таблицы. Каждая коллекция предоставляет доступ ко всем объектам ListRow и ListColumn в Таблице.

Свойство Range

Свойство Range возвращает всю таблицу, включая заголовок и итоговые строки. Тип объекта – Range. Свойство не может быть установлено.

Свойство HeaderRowRange

Свойство HeaderRowRange возвращает строку заголовка таблицы. Тип объекта – Range. Свойство не может быть установлено. Диапазон всегда представляет собой одну строку – строку заголовка – и распространяется на все столбцы таблицы. Если строка заголовка отключена, этому свойству присваивается значение Nothing.

Свойство DataBodyRange

Свойство DataBodyRange возвращает тело таблицы. Тип объекта – Range. Свойство не может быть установлено. Диапазон – это каждая строка между заголовком и общей строкой и распространяется на все столбцы таблицы. Если таблица не содержит строк, свойство DataBodyRange не возвращает Nothing (и ListRows.Count возвращает 0). Это единственный случай, когда свойство InsertRowRange возвращает объект диапазона, который можно использовать для вставки новой строки. В этом состоянии таблица выглядит как одна строка без каких-либо значений. Как только одна ячейка в таблице получает значение, InsertRowRange получает значение Nothing, а DataBodyRange – значение строк данных в таблице.

Свойство TotalRowRange

Свойство TotalRowRange возвращает итоговую строку Таблицы. Тип объекта – Range. Свойство не может быть установлено. Диапазон всегда представляет собой одну строку – строку итогов – и распространяется на все столбцы Таблицы. Если строка итогов отключена, это свойство имеет значение Nothing.

Свойство InsertRowRange

Свойство InsertRowRange возвращает текущую строку вставки Таблицы. Тип объекта – Range. Свойство не может быть установлено. В Excel 2007 и более поздних версиях InsertRowRange возвращает только первую строку данных и только тогда, когда таблица не содержит никаких данных. В противном случае он ничего не возвращает и фактически бесполезен.

Свойство ListRows

Свойство ListRows возвращает коллекцию всех строк в таблице DataBodyRange. Это тип объекта ListRows, который ведет себя очень похоже на объект Collection и содержит коллекцию объектов ListRow. Свойство не может быть установлено. На строки ссылаются по индексу, отсчитываемому от единицы (one-based index).[1] В пустой таблице нет строк. Метод Add объекта ListRows используется для вставки одной новой строки за один раз.

Свойство ListColumns

Свойство ListColumns возвращает коллекцию всех столбцов таблицы. Это тип объекта ListColumns, который ведет себя очень похоже на объект Collection и содержит коллекцию объектов ListColumn. Свойство не может быть установлено. На столбцы ссылается one-based. Таблица всегда содержит хотя бы один столбец.

Свойства структуры Таблиц

Таких свойств несколько. Все они являются членами объекта ListObject.

Свойство ShowAutoFilter возвращает или задает, включен ли Автофильтр. Свойство имеет логический тип. Если значение True, Автофильтр включен, False – отключен. Свойство представлено в пользовательском интерфейсе Excel, меню Данные –> Сортировка и фильтр –> Фильтр.

Свойство ShowAutoFilterDropDown возвращает или задает значение, указывающее отображается ли кнопка ниспадающего списка Автофильтра. Свойство имеет логический тип. Если значение True, кнопка отражается, False – не отражается. Если ShowAutoFilter имеет значение False, то свойство ShowAutoFilterDropDown изменить нельзя. Свойство представлено в пользовательском интерфейсе Excel, меню Работа с таблицами –> Конструктор –> Параметры стилей таблицы –> Кнопка фильтра.

Свойство ShowHeaders возвращает или задает, включена ли строка заголовка таблицы. Свойство имеет логический тип. Если значение True, строка заголовка таблицы включена, False – отключена. Свойство представлено в пользовательском интерфейсе Excel, меню Работа с таблицами –> Конструктор –> Параметры стилей таблицы –> Строка заголовков.

Свойство ShowTotals возвращает или задает включена ли строка итогов. Свойство имеет логический тип. Если значение True, строка итогов включена, False – отключена. Свойство представлено в пользовательском интерфейсе Excel, меню Работа с таблицами –> Конструктор –> Параметры стилей таблицы –> Строка итогов.

Свойства стилей Таблиц

Этих свойств также несколько. Все они являются членами объекта ListObject.

Свойство TableStyle возвращает или задает имя стиля таблицы. Свойство имеет тип Variant. Чтобы изменить стиль таблицы, необходимо задать имя нужного стиля. При назначении стиля таблицы к таблице применяются только элементы стиля, определенные в этом стиле (подробнее см. Глава 7. Форматирование Таблиц Excel). Чтобы определить имя стиля, наведите курсор мыши на нужный стиль в галерее стилей таблиц, пока Excel не отобразит имя этого стиля:

Ris. 9.2. Opredelenie imeni stilya tablitsy

Рис. 9.2. Определение имени стиля таблицы

Чтобы присвоить это имя свойству TableStyle, используйте код:

ActiveSheet.ListObjects(«qryCrosstab2»).TableStyle = «TableStyleLight21»

Здесь qryCrosstab2 – имя Таблицы. Внутренние имена всех встроенных стилей не содержат пробелов и английские, хотя имена, отображаемые на ленте, содержат пробелы и русифицированы. Чтобы узнать имя таблицы, которое нужно использовать в коде VBA, запустите запись макроса, присвойте стиль, завершите запись макроса, и посмотрите его код.

Свойство TableStyle представлено в пользовательском интерфейсе Excel в виде массива кнопок в группе Работа с таблицами –> Конструктор –> Стили таблиц.

Свойство ShowTableStyleColumnStripes возвращает или задает, форматируются ли нечетные столбцы таблицы иначе, чем четные столбцы. Свойство имеет логический тип. Если значение True, нечетные столбцы таблицы форматируются иначе, чем четные столбцы, как определено в заданном стиле таблицы. Нечетные столбцы форматируются с использованием параметров полосы первого столбца стиля таблицы, а четные строки форматируются с использованием параметров полосы второго столбца стиля таблицы. Если ShowTableStyleColumnStripes имеет значение False, столбцы таблицы не форматируются с использованием назначенного стиля таблицы. Свойство ShowTableStyleColumnStripes представлено в пользовательском интерфейсе Excel в виде флажка на ленте Работа с таблицами –> Конструктор –> Параметры стилей таблицы –> Чередующиеся столбцы.

Обратите внимание, что по умолчанию количество столбцов в каждой полосе равно одному, но вы можете изменить его на большее число для элементов полосы первого столбца и полосы второго столбца независимо. Дополнительную информацию смотрите в главе 7.

Свойство ShowTableStyleRowStripes возвращает или задает, форматируются ли нечетные строки таблицы иначе, чем четные строки. Свойство имеет логический тип. Если значение True, нечетные строки таблицы форматируются иначе, чем четные строки, как определено в заданном стиле таблицы. Нечетные строки форматируются с использованием первой полосы строк стиля таблицы, а четные строки форматируются с использованием второй полосы строк стиля таблицы. Если свойству ShowTableStyleRowStripes присвоено значение False, строки таблицы не форматируются с использованием назначенного стиля таблицы. Это свойство эквивалентно флажку на ленте Работа с таблицами –> Конструктор –> Параметры стилей таблицы –> Чередующиеся строки.

Свойство ShowTableStyleFirstColumn возвращает или задает, выделяется ли первый столбец. Свойство имеет логический тип. Если значение True, первый столбец таблицы форматируется так, как определено в настройках первого столбца назначенного стиля таблицы. Если установлено значение False, первый столбец таблицы не форматируется в соответствии с заданным стилем таблицы. Это свойство представлено в пользовательском интерфейсе Excel в виде флажка на ленте Работа с таблицами –> Конструктор –> Параметры стилей таблицы –> Первый столбец.

Свойство ShowTableStyleLastColumn возвращает или задает, выделяется ли последний столбец. Свойство имеет логический тип. Если значение True, последний столбец таблицы форматируется так, как определено в настройках последнего столбца назначенного стиля таблицы. Если установлено значение False, последний столбец таблицы не форматируется в соответствии с заданным стилем таблицы. Это свойство представлено в пользовательском интерфейсе Excel в виде флажка на ленте Работа с таблицами –> Конструктор –> Параметры стилей таблицы –> Последний столбец.

Другие свойства объекта Таблицы

В следующих разделах рассматриваются свойства объекта таблицы для использования в VBA. Они отличаются от методов.

Свойство Active возвращает True, если активная ячейка находится в пределах таблицы, включая заголовок и итоговые строки; в противном случае оно возвращает False. Свойство имеет логический тип. Свойство не может быть установлено.

Свойство AlternativeText возвращает или задает замещающий текст таблицы. Свойство имеет строковый тип. Установка этого свойства перезаписывает любое предыдущее значение. Это свойство представлено в пользовательском интерфейсе Excel в диалоговом окне Замещающий текст, доступ к которому можно получить, щелкнув правой кнопкой мыши в любом месте таблицы и пройдя по меню Таблица –> Замещающий текст. Это свойство отображается и редактируется в текстовом поле Заголовок.

Ris. 9.3. Zameshhayushhij tekst

Рис. 9.3. Замещающий текст

Свойство AutoFilter – это объект AutoFilter со своими собственными свойствами и методами. Его можно использовать для проверки настроек Автофильтра и повторного применения или очистки настроек Автофильтра в таблице. Он не используется для установки фильтров; для этого используется метод AutoFilter объекта Range.

Свойство Comment возвращает или задает комментарий таблицы. Свойство имеет строковый тип. Это свойство, добавленное в Excel 2007, представлено в пользовательском интерфейсе Excel в диалоговом окне Диспетчер имен, доступ к которому можно получить, пройдя по меню Формулы –> Определенные имена –> Диспетчер имен. Комментарий (примечание) отображается в правом столбце, и вы можете изменить его, кликнув на кнопку Изменить (рис. 9.4). Напомним, поскольку все Таблицы именуются, их имена отражаются в окне Диспетчер имен.

Ris. 9.4. Dispetcher imen

Рис. 9.4. Диспетчер имен

Свойство DisplayName возвращает или задает имя таблицы. Свойство имеет строковый тип. При назначении имени применяются те же ограничения, что и при изменении имени таблицы в пользовательском интерфейсе Excel; например, оно не может дублировать иное имя и не может содержать пробелов. Это свойство, добавленное в Excel 2007, ведет себя почти так же, как и свойство Name, но при использовании свойства DisplayName присваиваемое имя должно соответствовать ограничениям на имя таблицы, иначе возникает ошибка. Это свойство представлено в пользовательском интерфейсе Excel в виде поля ввода текста Работа с таблицами –> Конструктор –> Свойства –> Имя таблицы.

Свойство Name возвращает или задает имя таблицы. Свойство имеет строковый тип. В отличие от свойства DisplayName, когда вы присваиваете значение свойству Name, Excel изменяет имя так, чтобы оно соответствовало правилам имени таблицы. Например, он меняет пробелы на подчеркивания и, если имя уже существует, добавляет к нему символ подчеркивания, за которым следует число. Это свойство представлено в пользовательском интерфейсе Excel в виде поля ввода текста Работа с таблицами –> Конструктор –> Свойства –> Имя таблицы.

Чтобы избежать проблем, используйте свойство DisplayName вместо свойства Name для присвоения имени таблице. Свойство DisplayName создает ошибку, если имя является незаконным или уже определено в другом месте. С другой стороны, Excel будет искажать значение, присвоенное свойству Name, чтобы сделать его законным, и таким образом имя может оказаться не совсем тем, что вы намеревались.

Свойство Parent возвращает родителя таблицы. Свойство имеет тип объекта и всегда возвращает Worksheet. Свойство не может быть установлено.

Свойство QueryTable возвращает объект QueryTable, который ссылается на сервер списков. Это тип объекта QueryTable. Свойство не может быть установлено. Объект QueryTable предоставляет свойства и методы, позволяющие управлять таблицей. Следующий код публикует Таблицу на сервере SharePoint и называет опубликованный список Register. Затем он восстанавливает объект QueryTable для таблицы и устанавливает свойству MaintainConnection Таблицы значение True:

Dim Table As ListObject

Dim QueryTable As QueryTable

Dim PublishTarget(4) As String

Dim ConnectionString As String

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

PublishTarget(0) = «0»

PublishTarget(1) = «http://myserver/myproject»

PublishTarget(2) = «1»

PublishTarget(3) = «Register»

ConnectionString = Table.Publish(PublishTarget, True)

Set QueryTable = Table.QueryTable QueryTable.MaintainConnection = True

Свойство SharePointURL возвращает URL-адрес списка SharePoint. Свойство имеет строковый тип. Это свойство устанавливается при создании или обслуживании подключения к SharePoint и не может быть изменено. Это свойство представлено в пользовательском интерфейсе Excel в виде кнопки Работа с таблицами –> Конструктор –> Данные из внешней таблицы –> Экспорт –>  Экспорт таблицы в список SharePoint. Следующий код публикует существующую таблицу на сервере SharePoint с помощью SharePointURL и называет опубликованный список Register:

Dim Table As ListObject

Dim QueryTable As QueryTable

Dim PublishTarget(4) As String

Dim ConnectionString As String

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

PublishTarget(0) = «0»

PublishTarget(1) = Table.SharePointURL PublishTarget(2) = «1»

PublishTarget(3) = «Register»

ConnectionString = Table.Publish(PublishTarget, True)

Свойство Slicers возвращает коллекцию срезов, связанных с таблицей. Свойство имеет тип Slicers, который ведет себя очень похоже на объект Collection и содержит коллекцию объектов Slicer. Свойство не может быть установлено. Объект Slicers используется для добавления, управления и удаления срезов, связанных с таблицей. Каждый объект среза предоставляет свойства и методы, которые позволяют управлять срезом. Свойства срезов была добавлена в объект ListObject в Excel 2013.

В следующем примере срез добавляется и помещается на том же листе, что и Таблица. Чтобы добавить срез сначала нужно создать объект SlicerCache для каждого среза:

Dim Table As ListObject

Dim SlicerCache As SlicerCache

Dim Slicer As Slicer

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

Set SlicerCache = ThisWorkbook.SlicerCaches.Add(Table, «Category»)

SlicerCache.RequireManualUpdate = False

Set Slicer = SlicerCache.Slicers.Add(Table.Parent, , _

   «tblRegisterCategory», «Category», 100, 400)

Объект SlicerCache привязан к таблице и фильтруемому столбцу. Сам срез является визуальным представлением кэша среза и имеет родителя, имя, заголовок и позицию; он также имеет размер, но в приведенном выше примере используется размер по умолчанию. Свойство RequireManualUpdate объекта SlicerCache имеет значение False, чтобы избежать появления в срезе сообщения Устарело.

Следующий срез настроен на отображение категории Расходы (Expense) и скрытие категории Доходы (Income):

Dim Table As ListObject

Dim Slicer As Slicer

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

Set Slicer = Table.Slicers(«tblRegisterCategory»)

With Slicer.SlicerCache

   .SlicerItems(«Expense»).Selected = True

   .SlicerItems(«Income»).Selected = False

End With

Следующий срез настроен для отображения только одной категории:

Dim Table As ListObject

Dim Slicer As Slicer

Dim SlicerItem As SlicerItem

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

Set Slicer = Table.Slicers(«tblRegisterCategory»)

With Slicer.SlicerCache

   .ClearManualFilter

   For Each SlicerItem In .SlicerItems

      If SlicerItem.Name <> «Expense» Then

         SlicerItem.Selected = False

      End If

   Next SlicerItem

End Wit

В следующем примере происходит очистка фильтр среза:

Dim Table As ListObject

Dim Slicer As Slicer

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

Set Slicer = Table.Slicers(«tblRegisterCategory»)

Slicer.SlicerCache.ClearManualFilter

В следующем примере срез удаляется. Обратите внимание, что кэш среза также удаляется:

Dim Table As ListObject

Dim Slicer As Slicer

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

Set Slicer = Table.Slicers(«tblRegisterCategory»)

Slicer.Delete

Table.ShowAutoFilter = False

Обратите внимание, что свойство таблицы ShowAutoFilter имеет значение False, чтобы скрыть раскрывающийся список, который остается после удаления среза. Если Автофильтр таблицы был включен при создании среза, то этот шаг не требуется. Если Автофильтр таблицы не был включен до добавления среза, то после удаления среза раскрывающийся элемент управления Автофильтром остается только у столбца, для которого был удален срез.

Свойство Sort возвращает объект сортировки таблицы. Свойство имеет тип Sort object. Свойство не может быть установлено. В следующем примере Таблица сортируется по дате и описанию:

Dim Table As ListObject

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

With Table

   .Sort.SortFields.Add .ListColumns(«Date»).DataBodyRange,_

      xlSortOnValues, xlAscending

   .Sort.SortFields.Add .ListColumns(«Description»)._

      DataBodyRange, xlSortOnValues, xlAscending

   .Sort.Apply

   .Sort.SortFields.Clear

End With

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

Свойство SourceType возвращает текущий источник таблицы. Свойство имеет тип XlListObjectSourceType. Свойство не может быть установлено. Свойство может принимать следующие константы:

  • xlSrcExternal или 0 – источник является внешним источником данных, таким как сайт Microsoft SharePoint.
  • xlSrcModel или 4 – источником является модель Power Pivot.
  • xlSrcQuery или 3 – источником является запрос Power Query.
  • xlSrcRange или 1 – источником является объект Range.
  • xlSrcXml или 2 – источником является XML.

Свойство Summary возвращает или задает текст, используемый для замещающего текста при публикации таблицы. Свойство имеет строковый тип, введенный в Excel 2010. Установка этого свойства перезаписывает любое предыдущее значение. Это свойство представлено в пользовательском интерфейсе Excel в диалоговом окне Замещающий текст, доступ к которому можно получить, щелкнув правой кнопкой мыши в любом месте Таблицы и выбрав Таблица –> Замещающий текст (см. рис. 9.3). Это свойство отображается и редактируется в текстовом поле Описание.

Свойство TableObject возвращает объект TableObject Таблицы. Свойство имеет тип объекта TableObject. Свойство не может быть установлено. Объект TableObject предоставляет свойства и методы, позволяющие управлять объектами таблицы. TableObject – это объект, построенный на основе данных, полученных из модели Power Pivot. Он был введен в Excel 2013.

Свойство XmlMap возвращает объект XmlMap Таблицы, который предоставляет карту XML Таблицы. Свойство имеет тип объекта XmlMap. Объект XmlMap предоставляет свойства и методы, позволяющие управлять XML-картой. Свойство не может быть установлено.

Другие свойства Таблиц

Свойство ListColumn – это элемент в свойстве или коллекции ListColumns. ListColumn – это объект с рядом полезных свойств, включая следующие:

  • Range – ссылки на ячейки в столбце, включая заголовок и итоговые строки, если они включены.
  • DataBodyRange – тип объекта Range, который ссылается на столбец, исключая строки заголовка и итогов. Это пересечение диапазонов, представленных свойством Range объекта ListObject и диапазоном DataBodyRange объекта ListObject.
  • Index – относительный номер индекса столбца, представленного объектом ListColumn.
  • Parent – объект ListObject, которому принадлежит столбец.

ListColumn также включает метод Delete – удаляет столбец из Таблицы.

Каждый объект ListRow в коллекции строк имеет три часто используемых свойства: Range, которое ссылается на ячейки в этой строке; Index, которое является относительным номером индекса этой строки, и Parent, которое ссылается на объект ListObject, содержащий строку. Объект ListRow также имеет один метод Delete, который удаляет строку из таблицы.

Методы объекта Таблицы

Метод Delete удаляет Таблицу, включая все ее значения, формулы и форматирование. Не путайте этот метод с методом Unlist, который преобразует таблицу в обычный диапазон ячеек.

Метод ExportToVisio экспортирует и открывает в Visio динамическую сводную диаграмму в новом документе. Этот метод был добавлен в Excel 2007. Ошибка возникает, если Visio не установлен у вас на ПК (см. также Глава 3. Работа с таблицами Excel).

Метод Publish публикует таблицу в службе SharePoint. Он возвращает URL-адрес опубликованного списка в SharePoint в виде строки:

expression.Publish(Target, LinkSource)

где: expression – переменная, представляющая объект ListObject; Target – одномерный массив типа Variant, содержащий два или три элемента: URL-адрес SharePoint server, отображаемое имя списка и, при необходимости, описание списка; LinkSource – логическое значение. Если оно равно True, создает новую ссылку на новый список SharePoint. Если False, хранит ссылку на текущий список SharePoint и заменяет этот список, или, если нет никакого текущего списка, создает новый список на SharePoint без ссылок на него.

Метод Refresh обновляет таблицу из внешнего источника, если Таблица имеет такую связь. Если Таблица не связана с внешним источником данных, возвращает ошибку. Все изменения, внесенные в таблицу после последнего обновления, будут потеряны.

Метод Resize изменяет диапазон Таблицы на указанный диапазон. Метод принимает один параметр Range, который определяет новый диапазон Таблицы. Если строка заголовка включена, новый диапазон должен включать по крайней мере одну ячейку строки заголовка. Если строка заголовка отключена, новый диапазон должен содержать по крайней мере одну ячейку в первой строке диапазона тела данных. Столбцы можно добавлять и удалять с обоих концов, а строки можно добавлять и удалять только снизу. При удалении строк и столбцов все существующие данные в удаленных строках и столбцах остаются, но теперь находятся вне Таблицы. При добавлении строк и столбцов в Таблицу добавляются любые данные из дополнительных ячеек. После изменения размера структурированные ссылки в формулах в ячейках, отсутствующих в Таблице, преобразуются в абсолютные стандартные ссылки на ячейки. Если Таблица связана со списком SharePoint, можно добавлять и удалять только строки. Попытка добавить или удалить столбцы в связанной таблице приводит к ошибке.

Метод Unlink удаляет любую внешнюю ссылку на данные, если она существует.

Метод Unlist преобразует Таблицу в обычный диапазон ячеек. В интерфейсе Excel это эквивалентно команде Работа с таблицами –> Конструктор –> Параметры стилей таблицы –> Инструменты –> Преобразовать в диапазон.

Другие методы

Метод Add объекта ListObject добавляет новую таблицу, используя существующий список данных или другой источник. При использовании существующего заголовка числовые значения преобразуются в текст, а все повторяющиеся заголовки становятся уникальными путем добавления целых значений. Вот синтаксис этого метода:

expression.Add(SourceType, Source, LinkSource, _

   XlListObjectHasHeaders, Destination, TableStyleName)

где:

  • expression – переменная, представляющая объект ListObjects,
  • SourceType – передает константу XlListObjectSourceType, которая определяет тип источника, используемого для создания Таблицы. Необязательный параметр. Если опущен, предполагается xlSrcRange.
  • Source – если SourceType = xlSrcRange, то передайте объект Range, представляющий диапазон значений данных для преобразования в Таблицу. Необязательный параметр. Если опущен, используется текущий выбор. Если SourceType = xlSrcExternal, передайте массив строковых значений, указывающих соединение с источником, где элементы массива: 0 – URL-адрес сайта SharePoint, 1 – имя списка SharePoint, 2 – код представления GUID (уникальный шестнадцатеричный идентификатор представления),
  • LinkSource – логическое значение, указывающее, должен ли внешний источник данных быть связан с объектом ListObject. Если SourceType имеет значение xlSrcExternal, то значение по умолчанию равно True, и этот параметр не требуется передавать. Если значение передается и SourceType является xlSrcRange, генерируется ошибка.
  • XlListObjectHasHeaders – передает тип константы xlYesNoGuess, которая может принимать три значения: xlYes, xlNo или xlGuess. Константа указывает, имеют ли импортируемые данные метки столбцов. Если источник не содержит заголовков, Excel автоматически создает заголовки. Необязательный параметр. Если опущено, значение по умолчанию = xlGuess. Имя этого параметра должно было быть HasHeaders, но, когда метод был реализован, разработчики ошибочно использовали XlListObjectHasHeaders.
  • Destination – передает объект Range, который указывает ссылку на одну ячейку в качестве назначения для верхнего левого угла Таблицы. Ошибка генерируется, если диапазон относится к нескольким ячейкам. Этот параметр должен быть указан, если SourceType = xlSrcExternal. Он игнорируется, если SourceType имеет значение xlSrcRange. Диапазон назначения должен находиться на листе, содержащем коллекцию ListObjects, указанную в expression. Столбцы вставляются перед целевым диапазоном, чтобы соответствовать новому списку, предотвращая перезапись существующих данных. Необязательный параметр.
  • TableStyleName – передает имя стиля, который будет применен к Таблице. Необязательный параметр. Если опущен, применяется стиль по умолчанию.

Метод Add объекта ListRows вставляет одну новую строку в таблицу в указанной позиции. Вот синтаксис этого метода:

expression.Add(Position, AlwaysInsert)

где:

  • expression – переменная, представляющая объект ListRows.
  • Position – целое число, определяющее относительное положение новой строки. Новая строка вставляется над текущей строкой в этой позиции. Необязательный параметр. Если опущен, новая строка добавляется в нижнюю часть Таблицы.
  • AlwaysInsert – логическое значение, указывающее, следует ли всегда сдвигать данные в ячейках под последней строкой таблицы при вставке новой строки, независимо от того, является ли строка под таблицей пустой. При значении True ячейки под таблицей сдвигаются на одну строку вниз. При значении False, если строка под Таблицей пуста, Таблица расширяется, чтобы занять (добавить) эту строку без сдвига ячеек под ней; если строка под Таблицей содержит данные, эти ячейки сдвигаются вниз при вставке новой строки.

Метод Add возвращает объект ListRow, представляющий новую строку.

Метод Delete объекта ListRow удаляет строку Таблицы, представленную объектом ListRow.

Метод Add объекта ListColumns вставляет один новый столбец в Таблицу в указанной позиции:

  • expression – переменная, представляющая объект ListColumns.
  • Position – целое число, определяющее относительное положение нового столбца. Новый столбец вставляется перед текущим столбцом в этой позиции. Необязательный параметр. Если этот параметр опущен, новый столбец добавляется в правую часть Таблицы.

Этот метод возвращает объект ListColumn, представляющий новый столбец.

Метод Delete объекта ListColumn удаляет столбец Таблицы, представленный объектом ListColumn.

Метод Автофильтр объекта Range

Метод позволяет создать критерии Автофильтра для столбца, очистить критерии Автофильтра или переключить статус Автофильтра:

expression.AutoFilter(Field, Criteria1, Operator, _

   Criteria2, VisibleDropDown)

где:

  • expression – выражение, возвращающее объект Range.
  • Field – целочисленное смещение поля, на котором будет основан фильтр, где крайнее левое поле = 1. Необязательный параметр. Если опущен, то состояние Автофильтра (включено/выключено) переключается для всего диапазона. Отключение Автофильтра удаляет раскрывающиеся элементы управления Автофильтра.
  • Criteria1 – критерий в виде числа, строки или массива, например, 20 или "Расход". Можно использовать знаки равенства = и неравенства <>. Чтобы найти несколько строк, используйте функцию Array со значением оператора xlFilterValues, например, Array("Значение 1", "Значение 2"). Подстановочные знаки * (один или несколько символов) и ? (можно использовать любой отдельный символ). Если оператор xlTop10Items, то Criteria1 задает число элементов, например 10. Когда оператор xlFilterDynamic, Criteria1 – это константа xlDynamicFilterCriteria (описана ниже). Необязательный параметр. Если опущен, критерии для столбца очищаются.
  • Operator – передает константу XlAutoFilterOperator, определяющую тип фильтра. Необязательный параметр. Если опущен, то принимается равным 0, и Crtiteria1 рассматривается как простое значение для поиска; в этом случае, если в Crtiteria1 передается массив значений, то используется только последнее значение. Если этот параметр опущен, а Crtiteria1 не указан, то Автофильтр для указанного столбца будет очищен.
  • Criteria2 – второй критерий в виде числа, строки или массива. Он используется с Crtiteria1 и Operator для построения составных критериев или когда Operator = xlFilterValues, а фильтруются дата и время (описано ниже). Необязательный параметр.
  • VisibleDropDown – передает True, чтобы отобразить стрелку раскрывающегося списка Автофильтра для отфильтрованного поля, и False, чтобы скрыть раскрывающийся список Автофильтра для отфильтрованного поля. Необязательный параметр. Если опущен, принимает значение True.

Если заданы критерии фильтрации, то возвращаемое значение является значением Field. При переключении статуса Автофильтра возвращается значение True.

Значения констант оператора XlAutoFilterOperator:

  • xIAnd или 1 – фильтры с логическим И для Criteria1 and Criteria Оба критерия являются строками, задающими условия, например, ">0" и "<100".
  • xlBottom10Items или 4 – находит отображаемые элементы с наименьшим значением, где число элементов задается как число или строка в Criteria1, например, 5 или "5", то есть пять наименьших элементов. Столбец, указанный в параметре Field, должен содержать хотя бы одно число, иначе произойдет ошибка.
  • xlBottom10Percent или 6 – найти отображаемые элементы с наименьшим значением, где процент указан как число или строка в Criteria1, например, 20 или "20" для элементов в нижних 20%. Столбец, указанный в параметре Field, должен содержать хотя бы одно число, иначе произойдет ошибка.
  • xlFilterCellColor или 8 – находит цвет ячейки, где цвет указан как значение RGB в Criteria
  • xlFilterDynamic или 11 – динамический фильтр, где критерий фильтра задается как значение XlDynamicFilterCriteria в Criteria Динамический фильтр – это фильтр, изменяющийся в зависимости от какого-либо другого значения, например сегодняшней даты или среднего значения в столбце.
  • xlFilterFontColor или 9 – находит цвет шрифта, где цвет указан как значение RGB в Criteria
  • xlFilterIcon или 10 – находит значок, указанный в Criteria Значки извлекаются из свойства ActiveWorkbookIconSets. Свойство IconSets представляет собой набор объектов IconSets, в котором каждый набор иконок представляет собой набор из ряда иконок, таких как набор "3 стрелки (цветные)" или "3 Arrows (Colored)". В приведенном ниже примере извлекается первый значок в наборе "3 стрелки (цветные)":

ActiveWorkbook.IconSets(xlIconSet.xl3Arrows).Item(1)

Обратите внимание, что при вводе в редакторе VBA "xlIconSet." (включая точку) появится всплывающий список IntelliSense со всеми доступными ссылками на набор значков.

  • xlFilterValues или 7 – находит несколько значений, заданных в виде массива в Criteria1 или Criteria Значения в массиве должны быть строковыми и точно соответствовать отображаемому значению, если оно числовое; например, если соответствующие значения отображаются как "$25.00", передаваемое значение должно быть"$25.00". Criteria2 используется при поиске дат и времени. При поиске дат и времен массив передается как массив пар значений, где первое значение каждой пары является типом поиска, а второе –датой. Типы поиска: 0 – находит элементы в том же году, что и следующее значение даты / времени; 1 – находит элементы в том же месяце, что и следующее значение даты / времени; 2 – находит элементы на ту же дату, что и следующее значение даты / времени; 3 – находит элементы в тот же час, что и следующее значение даты / времени; 4 – находит элементы в ту же минуту, что и следующее значение даты / времени; 5 – находит элементы в ту же секунду, что и следующее значение даты / времени.

Может быть передано любое количество пар типа поиска и значения даты / времени. Все значения типа поиска должны находиться в нечетных позициях в массиве (1, 3, 5 и т.д.), а все значения даты/времени должны быть в четных позициях (2, 4, 6 и т.д.). Любое значение, переданное для типа поиска, которого нет в приведенном выше списке, создает ошибку. Любое значение, переданное для значения даты/времени, которое не является значением даты/времени, создает ошибку. Допустимо любое значение даты/времени, которое может быть введено в ячейку и распознано как дата. Некоторые примеры значений Criteria2:

Показать все элементы в 2014 году: Array(0, "1/1/2014")

Показать все элементы в 2014 году, когда текущий год 2014: Array(0, "1/1")

Показать все элементы в январе 2014 года: Array(1, "1/1/2014")

Показать все элементы 15 января 2014 года: Array(2, "15/1/2014")

Показывать все элементы 15, 20 и 25 января 2014 года: Array(2, "15/1/2014", 2, "20/1/2014", 2, "25/1/2014")

Показать все элементы в 2013 году и в январе 2014 года: Array(0, "1/1/2013", 1, "1/1/2014")

Показать все элементы в в 3 часа дня 15 января 2014 года: Array(3, "15/1/2014 15:00") или Array(3, "15/1/2014 3 PM")

Показать все элементы в 15:01 15 января 2014 года: Array (3, "15/1/2014 15:01") или Array(3, "15/1/2014 3:01 PM")

  • xlOr или 2 – логическим ИЛИ для Criteria1 and Criteria Оба критерия – это строки, задающие условие, например "<0" и ">100" для значений меньше нуля или больше 100.
  • xlTop10Items или 3 – находит отображаемые элементы с наибольшим значением, где число элементов задается как число или строка в Criteria1, например 5 или "5", то есть пять самых больших элементов. Столбец, указанный в параметре Field, должен содержать хотя бы одно число, иначе произойдет ошибка.
  • xlTop10Percent или 5 – находит отображаемые элементы с наибольшим значением, где процент указан как число или строка в Criteria1, например 20 или "20" для элементов в верхних 20%. Столбец, указанный в параметре Field, должен содержать хотя бы одно число, иначе произойдет ошибка.

Значения констант оператора XlDynamicFilterCriteria:

  • xlFilterToday – фильтрует все значения дат, равные сегодняшнему дню.
  • xlFilterYesterday – фильтрует все значения дат, равные вчерашнему дню.
  • xlFilterTomorrow – фильтрует все значения дат, равные завтрашнему дню.
  • xlFilterThisWeek – фильтрует все значения дат на текущей неделе.
  • xlFilterLastWeek – фильтрует все значения дат за предыдущую неделю.
  • xlFilterNextWeek – фильтрует все значения дат на следующей неделе.
  • xlFilterThisMonth – фильтрует все значения дат в текущем месяце.
  • xlFilterLastMonth – фильтрует все значения дат за предыдущий месяц.
  • xlFilterNextMonth – фильтрует все значения дат в следующем месяце.
  • xlFilterThisQuarter – фильтрует все значения дат в текущем квартале.
  • xlFilterLastQuarter – фильтрует все значения дат в предыдущем квартале.
  • xlFilterNextQuarter – фильтрует все значения дат в следующем квартале.
  • xlFilterThisYear – фильтрует все значения дат в текущем году.
  • xlFilterLastYear – фильтрует все значения дат за предыдущий год.
  • xlFilterNextYear – фильтрует все значения, относящиеся к следующему году.
  • xlFilterYearToDate – фильтрует все значения дат с начала года по сегодня.
  • xlFMterAMDatesInPeriodQuarterl – фильтрует все значения дат в квартале
  • xlFMterAMDatesInPeriodQuarter2 – фильтрует все значения дат в квартале 2.
  • xlFMterAMDatesInPeriodQuarter3 – фильтрует все значения дат в квартале 3.
  • xlFilterAllDatesInPeriodQuarter4 – фильтрует все значения дат в квартале 4.
  • xlFilterAllDatesInPeriodJanuary – фильтрует все значения дат в январе.
  • xlFilterANDatesInPeriodFebruary – фильтрует все значения дат в феврале.
  • xlFilterAllDatesInPeriodMarch – фильтрует все значения дат в марте.
  • xlFilterAllDatesInPeriodApril – фильтрует все значения дат в апреле.
  • xlFilterAllDatesInPeriodMay – фильтрует все значения дат в мае.
  • xlFilterAllDatesInPeriodJune – фильтрует все значения дат в июне.
  • xlFilterAllDatesInPeriodJuly – фильтрует все значения дат в июле.
  • xlFilterAllDatesInPeriodAugust – фильтрует все значения дат в августе.
  • xlFilterAllDatesInPeriodSeptember – фильтрует все значения дат в сентябре.
  • xlFilterAllDatesInPeriodOctober – фильтрует все значения дат в октябре.
  • xlFilterAllDatesInPeriodNovember – фильтрует все значения дат в ноябре.
  • xlFilterAllDatesInPeriodDecember – фильтрует все значения дат в декабре.
  • xlFilterAboveAverage – фильтрует все значения выше среднего.
  • xlFilterBelowAverage – фильтрует все значения ниже среднего.

Доступ к элементам Таблицы

Хотя свойства ListObject, ListColumns, ListRows предоставляют доступ к основным частям таблицы, существуют и другие способы доступа к элементам таблицы с использованием синтаксиса структурированных ссылок, описанного в главе 4. Эти способы могут быть более удобными, в зависимости от стиля программирования и предпочтений. В приведенных ниже примерах предполагается, что есть Таблица с именем "tblRegister" на листе с именем "Register" с заголовками столбцов "Date", "Description", "Category" и "Amount":

Ris. 9.5. Tablitsa

Чтобы использовать структурированную ссылку, используйте объект Range для извлечения диапазона, описанного ссылкой. Объект Range является дочерним объектом многих объектов Excel, включая объекты Application и Worksheet. При использовании объекта Range с объектом Application ссылка должна иметь глобальную область действия. При использовании Range с Worksheet (или Sheet) ссылка может иметь глобальную или локальную (Worksheet) область.

Область действия имени определяет, откуда к нему можно получить доступ. Ссылка с глобальной областью действия может быть доступна из любого объекта. На ссылку с локальной областью действия можно ссылаться только из листа, на котором определена конкретная ссылка.

Имена таблиц определены глобально, то есть, вы можете получить к ним доступ из любого модуля кода, не уточняя ссылку на объект листа, в котором находится таблица. Например, следующие ссылки эквивалентны:

ThisWorkbook.Worksheets(«Register»).Range(«tblRegister[Date]»)

Application.Range(«tblRegister[Date]»)

Range(«tblRegister[Date]»)

[tblRegister[Date]]

Чтобы соответствовать этому правилу, Excel требует, чтобы каждая Таблица в книге имела уникальное имя. Это правило управляет всеми глобальными именами, а не только именами Таблиц.

Чтобы уменьшить вероятность коллизии имен, можно предварить все имена таблиц общим префиксом, часто называемым «венгерской нотацией», описанной в главе 2, например, "tbl".

Excel 2003 не поддерживает структурированные ссылки. Существуют также некоторые различия между Excel 2007, 2010 и 2013 с точки зрения поддержки структурированных ссылок.

Создание и присвоение имени Таблице

Таблицы создаются с помощью метода Add объекта ListObjects. После создания новой Таблицы свойству DisplayName объекта ListObject присваивается имя новой Таблицы. Имя Таблицы, присваиваемое по умолчанию, зависит от источника Таблицы: xlSrcRange (диапазон данных на листе), xlSrcExternal (внешний источник данных), xlSrcModel (модель данных Power Pivot) и xlSrcQuery (запрос). Тип источника xlSrcXml (источник XML) не рассматривается, но показаны обходные пути.

Использование диапазона данных

В этом примере создается новая таблица, использующая существующий диапазон данных с заголовками. Параметр SourceType имеет значение xlSrcRange:

Dim TableRange As Range

Dim Table As ListObject

Set TableRange = ThisWorkbook.Worksheets(«Register»). _

   Range(«A1»).CurrentRegion

Set Table = ThisWorkbook.Worksheets(«Register»). _

   ListObjects.Add(xlSrcRange, TableRange, ,xlYes)

Table.DisplayName = «tblRegister»

Обратите внимание, что четвертый параметр, xlYes, сообщает Excel, что список данных уже содержит заголовки. В этом примере Таблица будет названа сразу же после ее создания; это поможет вам найти объект ListObject позже.

Использование модели данных Power Pivot

В этом примере для создания соединения с базой данных SQL Server используется объект TableObject. Таблица SQL "Product" добавляется в модель данных Power Pivot. Таблица помещается на рабочий лист "Sheet1" в ячейку A1. Поскольку взаимодействие происходит с моделью данных, то вместо объекта ListObject с xlSrcModel, переданного для SourceType, должен использоваться объект TableObject. Измените текст "YourServerName" на имя нужного SQL-сервера. Используется база данных AdventureWorks2012:

Dim SQLConnection As WorkbookConnection

Dim TargetWorksheet As Worksheet

Dim Table As TableObject

Dim ConnectionString As String

Set TargetWorksheet = ThisWorkbook.Worksheets(«Sheet1»)

ConnectionString = «OLEDB;Provider=SQLOLEDB.1; _

   Integrated Security=SSPI;» & «Initial Catalog _

   =AdventureWorks2012;Data Source=YourServerName»

Set SQLConnection = ActiveWorkbook.Connections.Add2(«FriendlyName», _

   «Description», ConnectionString, «Product», 3, True)

With TargetWorksheet

   Set Table = .ListObjects.Add(SourceType:=xlSrcModel, _

   Source:=SQLConnection, Destination:=.Range(«A1»)).NewTable

End With

Table.ListObject.DisplayName = «tblNewTable»

Константа xlSrcModel была добавлена в Excel 2013.

В следующем примере предполагается, что книга уже имеет соединение SQL Server с Таблицей в модели данных Power Pivot, и задача состоит в том, чтобы извлечь данные из таблицы модели данных в новую Таблицу Excel. Тип источника – xlSrcModel, и предполагается, что имя Таблицы модели данных – "Product". Этот пример работает только в Excel 2013:

Dim ModelSource As Model

Dim SourceTable As ModelTable

Dim TargetWorksheet As Worksheet

Dim Table As TableObject

Set TargetWorksheet = ThisWorkbook.Worksheets(«Sheet1»)

Set ModelSource = ThisWorkbook.Model

Set SourceTable = ModelSource.ModelTables(«Product»)

Set Table = TargetWorksheet.ListObjects.Add(SourceType:=xlSrcModel, _

   Source:=SourceTable.SourceWorkbookConnection, _

   LinkSource:=True, Destination:=DestinationSheet.Range(«A1»)).TableObject

Table.Refresh

Использование запроса Power Query

В этом примере объект QueryTable используется для создания соединения с базой данных SQL Server. Таблица "Product" добавляется на лист "Sheet1" в ячейку А1. Измените текст "YourServerName" на имя нужного SQL-сервера. Используется база данных AdventureWorks2012:

Dim TargetWorksheet As Worksheet

Dim Table As QueryTable

Dim ConnectionString As String

Set TargetWorksheet = ThisWorkbook.Worksheets(«Sheet1»)

ConnectionString = «OLEDB;Provider=SQLOLEDB.1;Integrated Security=SSPI;» _

   & «Initial Catalog=AdventureWorks2012;Data Source=YourServerName»

Set Table = TargetWorksheet.ListObjects.Add(SourceType:=xlSrcExternal, _

   Source:=ConnectionString, LinkSource:=True, _

   Destination:=DestinationSheet.Range(«A1»)).QueryTable

Table.CommandText = Array(«»«AdventureWorks2012»«.»«Production»«.»«Product»«»)

Table.CommandType = xlCmdTable

Table.Refresh BackgroundQuery:=False

Table.ListObject.DisplayName = «tblNewTable»

Константа xlSrcQuery была добавлена в Excel 2007.

При использовании xlSrcExternal необходимо указать параметр назначения. При использовании объекта QueryTable необходимо задать свойства CommandText и CommandType перед обновлением соединения.

В этом примере используется тип источника xlSrcExternal, который используется для любого внешнего подключения к данным. Передача xlSrcQuery для параметра SourceType приводит к тому же результату. Как правило, xlSrcQuery используется для подключения к базе данных, а xlSrcExternal используется для подключения к SharePoint.

Использование источника XML

По замыслу, метод Add объекта ListObjects с типом источника xlSrcXml должен создать объект ListObject, используя в качестве источника XML-файл. Однако этот метод ненадежен, и нет известных рабочих примеров его использования. Для импорта исходного файла XML в Таблицу рекомендуется использовать два метода. Во-первых, необходимо импортировать XML-файл в новую пустую книгу:

Workbooks.OpenXML Filename:=«C:XML File Name.xml», _

   LoadOption:=xlXmlLoadImportToList

Во-вторых, необходимо импортировать XML-файл в существующий лист в указанном диапазоне.:

ActiveWorkbook.XmlImport URL:=«C:XML File Name.xml», _

   ImportMap:=Nothing, Overwrite:=True, _

   Destination:=Range(«A1»)

В этих примерах, если указанный источник XML не ссылается на схему, Excel создает ее на основе того, что он найдет в указанном XML-файле.

Информация о Таблице

В следующих примерах предполагается, что DataBodyRange является допустимым объектом диапазона. Если в Таблице нет существующих строк (то есть если ListRows.Count равно 0), любая ссылка на DataBodyRange вернет ошибку.

Определение того, существует ли таблица

Это не простая задача, так как имя таблицы, которой нет, может использоваться с коллекцией ListObjects. В следующем коде показано, как использовать обработку ошибок для определения того, существует ли таблица:

Dim Table As ListObject

Set Table = Nothing

On Error Resume Next

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

On Error GoTo 0

If Table Is Nothing Then

   Debug.Print «Table does not exist»

Else

   Debug.Print «Table exists»

End If

Зачем устанавливать объектную переменную равную Nothing, прежде чем пытаться присвоить ей значение? В приведенном выше случае это не обязательно, поскольку VBA инициализирует каждую переменную, когда она определена с помощью оператора Dim. Но он включен выше в качестве примера написания надежного кода, потому что, если возникает ошибка, переменная не трогается и, если она уже содержит ссылку на другой объект, следующий тест не даст желаемого результата.

Определение адреса таблицы

В следующем примере выводится адрес Таблицы и адрес DataBodyRange Таблицы:

Dim Table As ListObject

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

Debug.Print «Table’s address: « & Table.Range.Address

Debug.Print «Table’s data body range address: « _

   & Table.DataBodyRange.Address

Определение количества строк

Количество строк в таблице определяется с помощью свойства Count объекта ListRows:

Dim Table As ListObject

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

Debug.Print «Number of rows: « & Table.ListRows.Count

Свойство Count возвращает 0, если таблица пуста (то есть имеет одну строку, готовую для ввода данных, и нет данных ни в одной ячейке).

Определение количества столбцов

Количество столбцов в таблице определяется с помощью свойства Count объекта ListColumns:

Dim Table As ListObject

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

Debug.Print «Number of columns: « & Table.ListColumns.Count

Определение того, существует ли столбец

Это также непростая задача. В следующем коде показано, как использовать обработку ошибок для определения того, существует ли столбец:

Dim Table As ListObject

Dim ListColumn As ListColumn

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

Set ListColumn = Nothing

On Error Resume Next

Set ListColumn = Table.ListColumns(«Description»)

On Error GoTo 0

If ListColumn Is Nothing Then

   Debug.Print «Column does not exist»

Else

   Debug.Print «Column exists»

End If

Добавление строк

Существует несколько способов добавления новых строк в Таблицу. Если вы добавляете одну строку, используйте метод Add объекта ListRows. Он возвращает объект ListRow, который затем можно использовать для добавления значений в эту новую строку:

Dim Table As ListObject

Dim NewRow As ListRow

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

Set NewRow = Table.ListRows.Add

With NewRow.Range

   .Columns(1).Value = #1/1/2015#

   .Columns(2).Value = «Transaction 20»

   .Columns(3).Value = «Expense»

   .Columns(4).Value = 75

End With

Обратите внимание, что в этом примере параметр Position не был передан методу Add, что привело к добавлению новой строки в конец таблицы. Чтобы вставить новую строку в определенную позицию таблицы, используйте параметр Position.

Чтобы добавить более одной строки в нижнюю часть таблицы, удобнее добавлять строки за один шаг, чем вызывать метод Add объекта ListRows несколько раз. В следующем примере строка итогов отключена, новые данные копируются в пустые ячейки непосредственно под Таблицей, после чего строка итогов включается. (Если функция TotalRow не отключена, Таблица не распознает новые строки и поэтому не расширяется для их включения.) Новые данные копируются из диапазона A2:D11 на листе Data:

Dim Table As ListObject

Dim NewValues As Variant

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

NewValues = ThisWorkbook.Worksheets(«Data»).Range(«A2:D11»).Value

Table.ShowTotals = False

With Table.DataBodyRange

   .Resize(10).Offset(.Rows.Count).Value = NewValues

End With

Table.ShowTotals = True

Чтобы вставить несколько строк в середину таблицы, используйте метод Insert объекта Range для вставки пустых ячеек, а затем эти ячейки заполняются новыми данными. В следующем примере 10 строк данных вставляются после существующей строки 2 (и перед строкой 3):

Dim Table As ListObject

Dim NewValues As Variant

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

NewValues = ThisWorkbook.Worksheets(«Data»).Range(«A2:D11»).Value

With Table.DataBodyRange

   .Resize(10).Offset(2).Insert Shift:=xlShiftDown

   .Resize(10).Offset(2).Value = NewValues

End With

Удаление строк

Метод, который вы используете, зависит от того, сколько строк вы хотите удалить.

Удаление одной строки

Для удаления одной строки используется метод Delete объекта ListRow:

Dim Table As ListObject

Dim ListRow as ListRow

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

Set ListRow = Table.ListRows(3)

ListRow.Delete

Переменной ListRow присваивается третий объект ListRow в коллекции ListRows, а затем вызывается метод Delete объекта ListRow. Вот альтернативная, более короткая версия примера, которая не требует переменной ListRow:

Dim Table As ListObject

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

Table.ListRows(3).Delete

Удаление нескольких строк

Удаление нескольких строк одновременно требует использования метода Delete объекта Range. В следующем примере удаляются 10 строк, начиная со строки 3:

Dim Table As ListObject

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

Table.DataBodyRange.Resize(10).Offset(2).Delete

Удаление всех строк

В следующем примере удаляются все строки таблицы:

Dim Table As ListObject

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

Table.DataBodyRange.Delete

В этом примере объекту DataBodyRange после завершения кода присваивается значение Nothing. Любые последующие ссылки на этот объект возвращают ошибку, если в Таблицу не добавлена хотя бы одна строка.

Циклы

В первом примере выполняется цикл по всем строкам Таблицы, добавляя в переменную TotalExpenses значения всех строк в столбце Expense (расходы) и выводя результат в окно Immediate:

Dim Table As ListObject

Dim ListRow As ListRow

Dim TotalExpenses As Double

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

For Each ListRow In Table.ListRows

   If ListRow.Range.Columns(3).Value = «Expense» Then

      TotalExpenses = TotalExpenses + ListRow.Range.Columns(4).Value

   End If

Next ListRow

Debug.Print «Total expenses: « & TotalExpenses

Ниже приведен альтернативный метод, использующий имена столбцов:

Dim Table As ListObject

Dim ListRow As ListRow

Dim TotalExpenses As Double

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

For Each ListRow In Table.ListRows

   If Intersect(ListRow.Range, Table.ListColumns(«Category»).Range) _

         .Value = «Expense» Then

      TotalExpenses = TotalExpenses + Intersect(ListRow.Range, Table.

      ListColumns(«Amount»).Range).Value

   End If

Next ListRow

Debug.Print «Total expenses: « & TotalExpenses

Во втором примере выполняется цикл по столбцам Таблицы, выводя имя каждого столбца на экран с помощью коллекции ListColumns и оператора For / Each:

Dim Table As ListObject

Dim ListColumn As ListColumn

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

For Each ListColumn In Table.ListColumns

   Debug.Print ListColumn.Name

Next ListColumn

Фильтрация

Одной из самых мощных особенностей Таблиц является их способность фильтровать строки. Объектная модель Excel предоставляет объект AutoFilter (дочерний элемент объекта ListObject) и метод AutoFilter (дочерний элемент объекта Range), что позволяет полностью контролировать процесс фильтрации в VBA. Используйте объект ListObject.AutoFilter для проверки текущих настроек Автофильтра, обновления Автофильтра и очистки Автофильтра. Используйте метод Range.AutoFilter для задания критериев Автофильтра.

Включение и выключение Автофильтра

Вы включаете и выключаете Автофильтр, задавая свойству ShowAutoFilter значения True (вкл.) и False (выкл.). В следующем примере показано, как включить Автофильтр:

Dim Table As ListObject

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

Table.ShowAutoFilter = True

Поскольку Автофильтр – это объект, который не имеет значения при отключенном Автофильтре, любой код, ссылающийся на какие-либо свойства и методы объекта Автофильтра, будет генерировать ошибку, если Автофильтр отключен. Чтобы избежать ошибок, убедитесь, что Автофильтр включен, и получите доступ к свойствам и методам объекта Автофильтра только в этом случае. Примеры ниже показывают, как осуществить эту проверку.

Вы также можете включать и отключать Автофильтр, повторно вызывая метод Range.AutoFilter без каких-либо параметров. Использование этого метода просто переключает состояние Автофильтра.

Определение состояния фильтрации

Объект Автофильтр используется для определения того, включен ли Автофильтр:

Dim Table As ListObject

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

If Table.ShowAutoFilter Then

   Debug.Print «AutoFilter is on»

Else

   Debug.Print «AutoFilter is off»

End If

Если Автофильтр включен, вы используете свойство FilterMode объекта Автофильтра, чтобы определить, установлены ли критерии фильтрации:

Dim Table As ListObject

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

If Table.ShowAutoFilter Then

   If Table.AutoFilter.FilterMode Then

      Debug.Print «Filtering is active»

   Else

      Debug.Print «Filtering is inactive»

   End If

Else

   Debug.Print «AutoFilter is off»

End If

Определение того, фильтруется ли столбец

Если Автофильтр включен, можно использовать свойство On объекта Filter, чтобы определить, имеет ли столбец активный критерий фильтра:

Dim Table As ListObject

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

If Table.ShowAutoFilter Then

   If Table.AutoFilter.Filters(3).On Then

      Debug.Print «Column 3 is being filtered»

   End If

Else

   Debug.Print «AutoFilter is off»

End If

Создание фильтров

Вы создаете (применяете) фильтры по одному столбцу за раз. Для добавления и удаления критериев фильтрации используется метод AutoFilter объекта Range. При применении критерия Автофильтра строка заголовка включается автоматически. В примерах ниже предполагается, что Таблица не имеет активных критериев фильтрации: Ниже приведены примеры, каждый из которых начинается с этих двух строк кода. Предполагается, что Таблица не имеет активных критериев фильтрации:

Dim Table As ListObject

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

В следующем примере фильтруются строки со значением Expense в третьем столбце.:

Table.Range.AutoFilter Field:=3, Criteria1:=«Expense»

А здесь фильтруются строки с Expense или Income в третьем столбце.:

Table.Range.AutoFilter Field:=3, _

   Criteria1:=Array(«Expense», «Income»), Operator:=xlFilterValues

Ниже показаны только строки со значениями во втором столбце, которые начинаются с Transaction:

Table.Range.AutoFilter Field:=2, Criteria1:=«Transaction*»

Строки в четвертом столбце со значениями больше нуля:

Table.Range.AutoFilter Field:=4, Criteria1:=«>0»

Строки с Income в третьем столбце и значениями более 100 – в четвертом:

Table.Range.AutoFilter Field:=3, Criteria1:=«Income»

Table.Range.AutoFilter Field:=4, Criteria1:=«>100»

Повторное применение критериев активного фильтра

Видимость строк в отфильтрованной таблице может не совпадать с критериями фильтра при изменении данных и добавлении новых строк. Эту ситуацию можно исправить, повторно применив критерии активного фильтра:

Dim Table As ListObject

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

If Table.ShowAutoFilter Then

   Table.AutoFilter.ApplyFilter

End If

Очистка фильтра одного столбца

Вы можете очистить фильтр одного столбца, используя метод AutoFilter и указав только параметр Field. В следующем примере очищаются критерии фильтра третьего столбца:

Dim Table As ListObject

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

Table.Range.AutoFilter Field:=3

Очистка всех фильтров

Вы можете очистить критерии фильтрации для всех столбцов за один шаг, не отключая Автофильтр, вызвав метод ShowAllData:

Dim Table As ListObject

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

If Table.ShowAutoFilter Then

   Table.AutoFilter.ShowAllData

End If

Скрытие раскрывающихся элементов управления по столбцам

Вы можете скрыть раскрывающиеся элементы управления Автофильтра в определенных столбцах. В следующем примере показано, как скрыть раскрывающийся элемент управления AutoFilter во втором столбце Таблицы:

Dim Table As ListObject

Set Table = ThisWorkbook.Worksheets(«Register»).ListObjects(«tblRegister»)

If Table.ShowAutoFilter Then

   Table.Range.AutoFilter Field:=2, VisibleDropDown:=False

End If

Пользовательские процедуры

В следующих разделах приведены некоторые пользовательские процедуры. Более надежные версии этих программ и ряд других программ, а также полезные утилиты и библиотеки доступны по адресу http://exceltables.com/.

Делаем объемную вставку

Следующая функция вставляет массив значений в Таблицу и возвращает новые строки в виде диапазона. Если задана строка, то значения вставляются выше этой строки; в противном случае значения добавляются в нижнюю часть Таблицы. Функция также сопоставляет столбцы значений со столбцами Таблицы с помощью параметра ColumnAssignmentS. Дополнительные сведения о параметрах см. в комментариях к процедуре.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

Public Function BulkInsertIntoTable( _

      ByVal Table As ListObject, _

      ByVal Values As Variant, _

      Optional ByVal Position As Long = 1, _

      Optional ByVal ColumnAssignments As Variant _

   ) As Range

‘ Insert an array of values into a Table. Optionally specify the row before

which the new rows are inserted. Optionally specify how the columns are

‘ assigned. The new rows in the Table are returned as a Range.

Syntax

‘ BulkInsertIntoTable(Table, Values, Position, ColumnAssignments)

Table A Table object.

‘ Values — A single value, a single dimension array of values, or a two

dimension array of values.

‘ Position — The row number before which the new rows are inserted. Optional.

If omitted then the new rows are appended to the end of the Table.

‘ ColumnAssignments — A single dimension array of integer values specifying

which Table column receives what column of values in the Values parameter.

‘ Each element in the array is a column number in the Table. The position of

the element in the array corresponds to the column in the Values array.

‘ Optional. If omitted then the values are placed in column order starting in

the first Table column. For example, passing Array(2,3,1) results in this

‘ column mapping:

Values column 1 is placed in Table column 2.

‘ Values column 2 is placed in Table column 3.

Values column 3 is placed in Table column 1.

Dim Calculation As XlCalculation

Dim ScreenUpdating As Boolean

Dim Result As Long

Dim TwoDimensionArray As Boolean

Dim WorkArray As Variant

Dim Column As Long

Dim SourceColumn As Long

Dim TargetColumn As Long

Dim ShowTotals As Boolean

Dim InsertRange As Range

‘ Exit if no values to insert

If IsEmpty(Values) Then Exit Function

Calculation = Application.Calculation

Application.Calculation = xlCalculationManual

ScreenUpdating = Application.ScreenUpdating

Application.ScreenUpdating = False

Normalize Values parameter must be a twodimension array

On Error Resume Next

Result = LBound(Values, 2)

TwoDimensionArray = Err.Number = 0

On Error GoTo 0

If Not TwoDimensionArray Then

   If Not IsArray(Values) Then

      Values = Array(Values)

   End If

   ReDim WorkArray(1 To 1, 1 To UBound(Values) LBound(Values) + 1)

   For Column = 1 To UBound(WorkArray, 2)

      WorkArray(1, Column) = Values(Column 1 + LBound(Values))

   Next Column

   Values = WorkArray

End If

‘ Normalize Position parameter

If Position < 0 Then

   Position = Table.ListRows.Count

End If

Position = Application.Max(1, Application.Min(Position, _

   Table.ListRows.Count+ 1))

Save total row setting and disable total

ShowTotals = Table.ShowTotals

Table.ShowTotals = False

‘ Insert the new rows

If Table.ListRows.Count > 0 And Position <= Table.ListRows.Count Then

Table.DataBodyRange.Resize(UBound(Values)). _

Offset(Position — 1).InsertShift:=xlShiftDown

End If

If Table.ListRows.Count > 0 Then

Set InsertRange = Table.DataBodyRange.Resize _

(UBound(Values)).Offset(Position — 1)

Else

Set InsertRange = Table.InsertRowRange.Resize(UBound(Values))

End If

If IsEmpty(ColumnAssignments) Or IsMissing(ColumnAssignments) Then

   InsertRange.Value = Values

Else

   For TargetColumn = LBound(ColumnAssignments) To _

      UBound(ColumnAssignments)

      SourceColumn = TargetColumn — LBound(ColumnAssignments) + 1

      If ColumnAssignments(TargetColumn) >= 1 And _

         ColumnAssignments(TargetColumn) <= _

            Table.ListColumns.Count Then

         InsertRange.Columns(ColumnAssignments(TargetColumn)) _

            .Value = Application.Index(Values, , SourceColumn)

      End If

   Next TargetColumn

End If

Set BulkInsertIntoTable = InsertRange

Restore the total row setting

Table.ShowTotals = ShowTotals

Application.Calculation = Calculation

Application.ScreenUpdating = ScreenUpdating

End Function

Восстановление форматирования и формул

Обычно Таблица поддерживает одинаковое форматирование и формулы во всех строках, исключая строки заголовка и итоговые строки. При изменении форматирования или формулы в ячейке столбца Таблицы Excel применяет это новое форматирование или формулу ко всему столбцу. Форматирование и формулы автоматически применяются к новым строкам по мере их добавления.

Форматирование или формулы Таблицы могут стать несогласованными, если вы вручную редактируете форматирование или применяете разные формулы в одном столбце Таблицы. Вы можете исправить столбец Таблицы, повторно применив форматирование ко всему столбцу плюс одна дополнительная строка внизу (строка итогов должна быть отключена, чтобы выполнить эту корректировку). Вы можете исправить формулу (преобразовать столбец обратно в вычисляемый столбец), применив формулу ко всему столбцу.

Процедура ниже выполняет это с помощью метода изменения размера Таблицы. Сначала Таблица изменяется, чтобы быть только одной строкой. Затем форматирование и формулы удаляются из всех строк таблицы от строки 2 до последней строки плюс одна строка. Наконец, диапазон Таблицы возвращается к тому, что было. На этом заключительном этапе Excel должен применить форматирование и формулы в первой строке ко всем строкам ниже первой строки. В результате получается последовательно отформатированная таблица, использующая первую строку данных в качестве шаблона для всех остальных строк. Код предполагает, что в Таблице есть по крайней мере одна строка данных:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

Public Sub RepairTable( _

      ByVal Table As ListObject _

   )

‘ Repair the Table’s formatting and formulas by making them consistent down the

‘ entire length of each column.

‘ Syntax

‘ RepairTable(Table)

Table A Table object (ListObject object).

Dim RowCount As Long

Dim ListColumn As ListColumn

Dim ShowTotals As Boolean

RowCount = Table.ListRows.Count

If RowCount < 2 Then Exit Sub

With Table

   ShowTotals = .ShowTotals

   .ShowTotals = False

   .Resize .HeaderRowRange.Resize(2)

   For Each ListColumn In .ListColumns

      With ListColumn.DataBodyRange.Resize( _

         Application.Max(RowCount, 1)).Offset(1)

         If Left(.Rows(1).Formula, 1) = «=» Then

            .Cells.Clear

         Else

            .Cells.ClearFormats

         End If

     End With

   Next ListColumn

   .Resize .HeaderRowRange.Resize(1 + RowCount)

   .ShowTotals = ShowTotals

End With

End Sub

Копирование стиля Таблицы в новую книгу

Нет простого способа скопировать стиль Таблицы из одной книги в другую. Следующий пример кода копирует стиль, присвоенный Таблице с именем "tblRegister", в книгу "Destination Workbook. xlsx":

Sub ExportTableStyle()

   Dim Source As Workbook

   Dim Target As Workbook

   Dim Table As ListObject

   Set Source = ThisWorkbook

   Set Target = Workbooks(«Destination Workbook.xlsx»)

   Set Table = Source.Worksheets(«Register»).ListObjects(«tblRegister»)

   Target.Worksheets.Add Before:=Target.Worksheets(1)

   Table.Range.Copy Target.Worksheets(1).Range(«A1»)

   Target.Worksheets(1).Delete

End Sub

[1] Различают три основных разновидности массивов: с отсчетом от нуля (zero-based), с отсчетом от единицы (one-based) и с отсчетом от специфического значения заданного программистом (n-based).

Bottom Line: Learn how to use a macro to create connection-only queries for all tables in the workbook.  This includes adding the data to the Data Model.

Skill Level: Advanced

Video Tutorial

Watch on Youtube & Subscribe to our Channel

Download the Excel File with Macro

The macro I’ve created is included in this Excel file. This is the same workbook I use in the video. You can download the file and add the macro to your Personal Macro Workbook.

If you’re new to Power Query, I recommend checking out this overview, and then using this tutorial to get it installed properly.

Speeding Up a Tedious Process

Creating connection-only queries to tables takes time.  I’ve detailed the steps of the process in this post: How to Combine Tables with Power Query. It basically involves accessing the Import Data window and selecting Only Create Connection for each and every table that you want to combine.

Import Data Window Only Create Connection

However, I’ve automated this process with a macro that takes less than one second to run. The run time will vary depending on how many tables your workbook has, but it’s pretty fast!

What the Macro Does

The macro creates connection-only queries in Power Query for all tables in the workbook. 

Queries and Connections Pane showing all connections

How the Macro Works

When you run the macro it:

  1. First double-checks that you intend to run it with a yes/no message box. Checkout video #4 in my Personal Macro Workbook video series to learn more about yes/no message boxes.
  2. The macro then asks the user if the data should be added to the Data Model. This is the same as pressing the checkbox on the Data Import Window.
  3. Then the macro loops through all of the tables in all of the worksheets and creates connections for each table.
  4. The macro will only create connections if a query for the table does NOT already exist.  It does not create duplicate queries for tables with existing connections.

Here is the VBA code for the macro:

Sub Add_Connection_All_Tables()
'Creates Connection Only Queries to all tables in the active workbook.

Dim wb As Workbook
Dim ws As Worksheet
Dim lo As ListObject
Dim sName As String
Dim sFormula As String
Dim wq As WorkbookQuery
Dim bExists As Boolean
Dim vbAnswer As VbMsgBoxResult
Dim vbDataModel As VbMsgBoxResult
Dim i As Long
Dim dStart As Double
Dim dTime As Double

  'Display message box to prompt user to run the macro
  vbAnswer = MsgBox("Do you want to run the macro to create connections for all Tables in this workbook?", vbYesNo, "Power Query Connect All Tables Macro")

  If vbAnswer = vbYes Then

      'Prompt user for Data Model option
    vbDataModel = MsgBox("Do you want to add the data to the Data Model?", vbYesNo + vbDefaultButton2, "Power Query Connect All Tables Macro")

    'Set variables
    dStart = Timer
    Set wb = ActiveWorkbook

        'Loop sheets and tables
    For Each ws In ActiveWorkbook.Worksheets
      For Each lo In ws.ListObjects

                sName = lo.Name
        sFormula = "Excel.CurrentWorkbook(){[Name=""" & sName & """]}[Content]"

                'Check if query exists
        bExists = False
        For Each wq In wb.Queries
          If InStr(1, wq.Formula, sFormula) > 0 Then
            bExists = True
          End If
        Next wq

                'Add query if it does not exist
        If bExists = False Then

                  'Add query
          wb.Queries.Add Name:=sName, _
                         Formula:="let" & Chr(13) & "" & Chr(10) & "    Source = Excel.CurrentWorkbook(){[Name=""" & sName & """]}[Content]" & Chr(13) & "" & Chr(10) & "in" & Chr(13) & "" & Chr(10) & "    Source"
          'Add connection
          wb.Connections.Add2 Name:="Query - " & sName, _
                              Description:="Connection to the '" & sName & "' query in the workbook.", _
                              ConnectionString:="OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=" & sName & ";Extended Properties=""""", _
                              CommandText:="SELECT * FROM [" & sName & "]", _
                              lCmdtype:=2, _
                              CreateModelConnection:=False, _
                              ImportRelationships:=False

                                        'Add to Data Model
          If vbDataModel = vbYes Then
            wb.Connections.Add2 Name:="Query - " & sName, _
                                Description:="Connection to the '" & sName & "' query in the workbook.", _
                                ConnectionString:="OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=" & sName & ";Extended Properties=", _
                                CommandText:="" & sName & "", _
                                lCmdtype:=6, _
                                CreateModelConnection:=True, _
                                ImportRelationships:=False
          End If

                    'Count connections
          i = i + 1

                  End If
      Next lo
    Next ws

    'Calc run time
  dTime = Timer - dStart

    MsgBox i & " connections have been created in " & Format(dTime, "0.0") & " seconds.", vbOKOnly, "Process Complete"

    End If

End Sub

How to Use It in Your Work

This is a great macro to add to your Personal Macro Workbook because you will be able to run it on any open workbook. If you don’t have your PMW set up yet, this tutorial will help you: How to Create a Personal Macro Workbook.

Then create a macro button by customizing the ribbon.  Check out this article on How to Add Macro Buttons to the Ribbon for details.

Custom Macro Ribbon in Excel - Power Query Connect All Tables

You can then run the macro on any open workbook.

Free Training Webinar on the Power Tools

Right now I’m running a free training webinar on all of the Power Tools in Excel. This includes Power Query, Power Pivot, Power BI, pivot tables, macros & VBA, and more.

It’s called The Modern Excel Blueprint. During the webinar I explain what these tools are and how they can fit into your workflow.

Modern Excel Blueprint Training Webinar Excel Campus Jon Acampora

You will also learn how to become the Excel Hero of your organization, that go-to gal or guy that everyone relies on for Excel help and fun projects.

The webinar is running at multiple days and times. Please click the link below to register and save your seat.

Click Here to Register for the Free Webinar

Conclusion

If you have multiple tables that you are looking to combine, this macro will save you tons of time establishing connections so that you can merge or append in Power Query.

If you use the macro, I’d love to hear how long it takes for the macro to create all of your connections. Leave a comment with the number of seconds it took!

Often we need to merge worksheets / workbooks containing lots of data. Imagine receiving periodical daily reports and wanting to quickly consolidate them to generate a weekly or monthly report… seems like a lot of work. Merging worksheets does not necessarily need to be hard… as long as you read through today’s post.

Looking to merge CSV or TXT files instead? Read this post

To exemplify the issue let’s consider a Workbook consisting of 2 worksheets (below named Sheet1 and Sheet2) with identical columns.

consolidate worksheets

What we want to do is merge these 2 worksheets into one consolidated worksheet. We may of course want to do this in multiple ways e.g. by:

  • Simply appending the worksheets to each other
  • Merging the data sets while removing duplicates

Here is the example result we want to achieve (Sheet2 appended to Sheet1 on a third separate Worksheet):
merging worksheets

In today’s Tip of the Day I will exemplify how to merge worksheets / tables (any number) with an option of eliminating duplicates.

Merging worksheets with VBA

Let’s first consider a simple piece of VBA code. The procedure below can handle any number of Worksheets – including Worksheets from external Workbooks as long as you have the Workbook open and provide it within the array of Worksheets passed to the procedure.

Sub Merge(ws() As Worksheet, destWs As Worksheet, headerInFirstRow As Boolean, removeDuplicates As Boolean)
    'Clear destination worksheet
    destWs.UsedRange.EntireRow.Delete
    Dim pasteRange As Range, header As Range, firstFreeRow As Range, w As Variant, copyRange As Range
    'Paste header
    If headerInFirstRow Then
        Set header = ws(0).UsedRange.Cells(1).EntireRow:
        header.Copy destWs.Cells(1).EntireRow
    End If
    Set firstFreeRow = destWs.UsedRange.Rows(destWs.UsedRange.Rows.Count).Offset(1).EntireRow
    'Paste worksheets
    For Each w In ws
        Set copyRange = w.UsedRange.Rows("" & _
            IIf(headerInFirstRow, 2, 1) & ":" & w.UsedRange.Rows.Count)
        copyRange.Copy firstFreeRow.Cells(1, 1)
        Set copyRange = Nothing
        Set firstFreeRow = destWs.UsedRange.Rows(destWs.UsedRange.Rows.Count).Offset(1).EntireRow
    Next w
    'Remove duplicates
    If removeDuplicates Then
        Dim colArr As Variant, col As Long: ReDim colArr(0 To destWs.UsedRange.Columns.Count - 1)
        For col = 1 To destWs.UsedRange.Columns.Count
            colArr(col - 1) = col
        Next col
        destWs.UsedRange.removeDuplicates Columns:=(colArr), header:=IIf(headerInFirstRow, xlYes, xlNo)
    End If
    'Clean
    Set firstFreeRow = Nothing: Set w = Nothing: Set header = Nothing
End Sub

A now a simple example of this procedure being used assuming the example data I referenced above. Let’s assume data on is on worksheets Sheet1 and Sheet2, the destination Worksheet will be Sheet3.

Sub TestMerge()
    Dim ws(0 To 1) As Worksheet
    Set ws(0) = Sheet1
    Set ws(1) = Sheet2
    Merge ws, Sheet3, True, False
End Sub

Notice that the Merge procedure accepts the following parameters:

  • ws – an array of Worksheets
  • destWs – the destination Worksheet
  • headerInFirstRow – if true assumes that the header is in the first row of each source Worksheet
  • removeDuplicates – if true remove all duplicates after merging the Worksheets

Simple enough right? Not too long. If you want to optimize it for best performance read this.

Merging worksheets with MS Query (SQL)

Now let’s consider a second approach – using MS Query (SQL). This is my personal favorite as MS Query SQL code is short, does not require VBA and the destination Worksheet can be refresh by simply right clicking on the table and hitting refresh.

To create a MS Query feel free to use my Excel SQL AddIn or follow the steps below:
merge worksheets excel
Follow the instructions below if you don’t have my Excel SQL AddIn:

Open the From Microsoft Query Wizard

Data ribbon and then selecting From Other Sources and From Microsoft Query -> till the end be sure to hit View Data or Edit Query in Microsoft Query to be able to provide your own SQL query.

Proceed according to Wizard to edit SQL Query

As we want to merge several Worksheets within our current Excel Workbook we need to select Excel Files as the designated data source for our MS Query:
Select From Excel Files data source
Next we need to select our Current Excel Workbook from the File Dialog:
Select your current Excel Workbook
Select the first Excel Worksheet you want to merge and click the right arrow > to drag it to the Columns in your Query section.
Select any Worksheet you want to merge to proceed
Next instead of Returning the Data hit the View data or edit Query in Microsoft Query radio button and proceed:
Proceed to edit the MS Query
A new Window should pop-up. Look for the SQL button to modify the existing MS Query:
Hit SQL to edit MS Query

Modify the SQL Query to merge Worksheets

A new SQL Window should pop-up. You can modify any number of Worksheets using this approach. Below I am assuming I want to merge two Worksheets – Sheet1 and Sheet2. The MS Query need to therefore look like this:

SELECT * FROM [Sheet1$] UNION ALL SELECT * FROM [Sheet2$]

Simply modify the existing MS Query in the SQL Window and hit OK.

What if you need to merge 3 Worksheets not just 1?

Simply append an additional UNION ALL like this:

SELECT * FROM [Sheet1$] UNION ALL SELECT * FROM [Sheet2$] UNION ALL SELECT * FROM [Sheet3$]

For additional Worksheets repeat this pattern

Return Data to selected Worksheet

Return Data to Excel WorkbookNow the pleasant part – loading the Query data. Look for the Return Data button, select a cell where the MS Query is supposed to load and hit OK.

Comment on using the MS Query approach

Simple and quick – this approach is more efficient than any VBA code we may develop as it is handled by the OLEDB driver. MS Query (SQL) is also more efficient in handling large chunks of data as compared to other approaches.

Merging worksheets with PowerQuery

If you are not familiar with PowerQuery feel free to download it from Microsoft here. PowerQuery features a lot of neat data-crunching / BI features. Let’s see how can we leverage PowerQuery to do our job.

Create tables from each source Worksheet

First what we need to do is link our source tables to PowerQuery so we can create the output query.
consolidate2
Select the whole range of each source worksheet (CTRL + A)
and select the From Table option from the PowerQuery ribbon. For this example I have named Sheet1 as Table1 and similarly with Sheet2.

Merge the Worksheets

So now that we have our Tables configured in PowerQuery we can append the 2 (or more). Hit the Append button from the Combine group in the PowerQuery ribbon.

PowerQuery - Combine

Next select Table1 from the first drop-down and Table2 from the second drop-down:

PowerQuery - Append

and hit OK

Note: When wanting to append multiple (>2) worksheets simply repeat this step. The first Table will need to be the Appended one from the remaining tables

That’s it! Similarly as with the MS Query example you can always easily refresh your query by right-clicking and hitting Refresh!

Summary

I hope you found these methods useful. On one last note I would like to share my thoughts on how these methods compare.

Personally I prefer to use MS Query (SQL) via my SQL AddIn. This sentiment may of course be partially as I used to work a lot with databases and am used to coding SQL. I know for most Excel users out there this is not the case. In such cases and if you only have a couple of Worksheets you need to merge on a regular basis I do suggest downloading the PowerQuery AddIn. It’s easy to use and also allows you to refresh your query easily. In all other scenarios feel free to use the VBA approach and simply customize your code to work best for you!

Let me know if you found this useful! And be sure to subscribe to more Tips on my Twitter or Facebook page!

Guest Post by Dany Hoter

After I published a post about manipulating relationships, Rob suggested that I take a step back and cover the entire scope of what’s possible with the object model.

Can you build a model from scratch? Can you add a new table to an existing table? Can you add calculated columns? What about calculated measures? , Can you change a connection for an existing table in the model?

The short answer to these questions is Yes, Yes, No, No, Yes

The longer version is the rest of this post. Everything in this post is NOT possible in Excel 2010 – this stuff works in 2013 only.

The object model consists of the following elements:

clip_image001

The only property that I found useful in this list is ModelRelationships collection which I used extensively in the previous post.

The ModelTables collection looks promising as it contains ModelTableColumns and could be the way to introduce new tables, new columns or even measures into the model. Unfortunately all these collections are read-only and cannot be used for adding to the model.

So how is still possible to add new tables or even to start a model from scratch?

It all has to do with the method add2 of the Connections collection.

This method can be used to add new tables to the data model from a variety of sources.

This is the definition of this method:

image

The two last Boolean parameters are related to adding connections to the data model.

I started by recording macros while importing data into Excel but I must admit that a lot of cleaning was needed after recording Smile

If you use any of these examples on an empty workbook, a data model will be created, the table(s) will be added to it and if relevant also relationships between the imported tables will be added.

So if you run this specific example that imports data from an OData feed available on the web it should always work:

Sub TwotablesFromOData()

ActiveWorkbook.Connections.Add2 _

“DataFeed_2_services-odata-org Multiple Tables”, “”, _

“DATAFEED;Data Source=https://services.odata.org/northwind/northwind.svc/;Namespaces to Include=*;Max Received Message Size=4398046511104;Integrated Security=SSPI;Keep Alive=true;Persist Security Info=false;Service Document Url=https://services.odata.org/northwind/northwind.svc/” _

, “””Order_Details””,””Orders”””, 6, True, False

End Sub

Creating from SQL server source instead

Creating from a Table

Sub AddSQLtables()

‘One or more tables from a SQL server database

‘Relationships are detected if they are declared in the database

ActiveWorkbook.Connections.Add2 _

“Connection Name”, “”, _

“OLEDB;Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Data Source=<SQL server – name>;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Use Encryption for Data=False;Tag with column collation when possible=False;Initial Catalog=AdventureWorksDW2008R2” _

, “””DimCustomer””,””DimGeography”””, 6, True, True

End Sub

Parameters need to be adjusted to your needs of course like server name, database and tables.

Notice the list of tables with the multiple quotes around them. You can include one or more tables or views. You can’t specify a subset of columns from a table.

The two True values tell Excel to add the tables to the model and to detect relationships.

Relationships between the table imported together are detected and if they exist they are added to the ModelRelationships collection

Creating from a SQL query

Sub Addsql()

‘A SQL query is used to create a table in the model.

‘ The table name cannot be changed and is <database name query>

ActiveWorkbook.Connections.Add2 _

“All fields from customer”, “”, _

“OLEDB;Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Data Source=<SQL server – name>;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Use Encryption for Data=False;Tag with column collation when possible=False;Initial Catalog=AdventureWorksDW2008R2” _

, “select * from “”DimCustomer”””, 2, True, True

End Sub

I couldn’t find a way to determine the name of the new table in the model L

Creating from Access tables

Sub AccessTables()

‘A collection of tables from Access. Relationships are detected

ActiveWorkbook.Connections.Add2 “Sales Retail”, “”, Array( _

“OLEDB;Provider=Microsoft.ACE.OLEDB.12.0;Password=””””;User ID=Admin;Data Source=C:UsersdanyhDocumentsSales Retail.accdb;Mode=Share D” _

, _

“eny Write;Extended Properties=””””;Jet OLEDB:System database=””””;Jet OLEDB:Registry Path=””””;Jet OLEDB:Database Password=””””;Jet OLED” _

, _

“B:Engine Type=6;Jet OLEDB:Database Locking Mode=0;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet O” _

, _

“LEDB:New Database Password=””””;Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don’t Copy Local” _

, _

“e on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False;Jet OLEDB:Support Complex Data=False;Jet O” _

, _

“LEDB:Bypass UserInfo Validation=False;Jet OLEDB:Limited DB Caching=False;Jet OLEDB:Bypass ChoiceField Validation=False” _

), “””Employees””,””departments”””, 6, True, True

Probably many parameters are optional. Again the main thing are the two last parameters which add the tables to the model and trigger relationships detection.

From a CSV file

Sub FromCsv()

ActiveWorkbook.Connections.AddFromFile _

“C:UsersdanyhDocumentsMyTable.csv”, True, False

End Sub

This example is using a different method but the last two parameters are the same

From a table in the same file

Sub FromTable()

ActiveWorkbook.Connections.Add2 _

“WorksheetConnection_Import tables.xlsm!TableName”, “”, _

“WORKSHEET;C:UsersdanyhDocumentsImport tables.xlsm”, _

“Import tables.xlsm!TableName”, 7, True, False

End Sub

From ODATA feed

Sub TwotablesFromOData()

ActiveWorkbook.Connections.Add2 _

“DataFeed_2_services-odata-org Multiple Tables”, “”, _

“DATAFEED;Data Source=https://services.odata.org/northwind/northwind.svc/;Namespaces to Include=*;Max Received Message Size=4398046511104;Integrated Security=SSPI;Keep Alive=true;Persist Security Info=false;Service Document Url=https://services.odata.org/northwind/northwind.svc/” _

, “””Order_Details””,””Orders”””, 6, True, False

End Sub

Скачать файл-примера

Как Вы могли убедиться из моих предыдущих постов, меры являются мощными инструментами анализа данных и позволяют производить немыслимые до этого виды расчётов. Однако, до сих пор при знакомствами с мерами мы использовали только одну таблицу t_sales. Но вся прелесть Power Pivot в том, что с его помощью можно производить расчёты, комбинируя данные из нескольких таблиц. По моему личному мнению, если бы даже Powe Pivot не имел встроенного движка функций DAX, одна только способность связывания таблиц, уже оправдывала бы его существование.

Создание связей

Так как же создаются связи между таблицами? Всё очень просто. Заходим в окно Power Pivot и в правом нижнем углу, нажимаем на иконку со всплывающей надписью «Диаграмма».

Либо по кнопке «Представление диаграммы» на вкладке «Главная».

Откроется окно представления диаграммы, в котором все таблицы нашей модели данных показаны в виде отдельных окошек, со списком колонок.

Как видим, эти таблицы между собою пока никак не связаны. Чтобы создать между ними связь, нам сначала нужно определить идентичные колонки. Идентичными колонками, называют колонки содержащие одинаковые данные. К примеру, и в таблице t_sales и в таблице t_products есть колонки КодПродукта, содержащие одинаковые данные (при этом не обязательно, чтобы названия колонок в обоих таблицах были одинаковыми). Свяжем эти две таблицы между собою кликнув по названию колонки КодПродукта в t_sales и удерживая левую кнопку мыши нажатой, перетащим эту колонку к другой колонке КодПродукта в t_products.

Точно также, связь между таблицами можно создать через команду «Создание связи» на вкладке «Конструктор».

Но можно ли создавать связь между таблицами по любым идентичным столбцам? Например столбцы «ЦенаЗаШтуку» в t_sales и «Цена» в t_products содержат одинаковые данные. Попробуем создать между ними связь путём перетаскивания. Power Pivot выдаст ошибку: «Не удалось создать связь, поскольку в каждом столбце содержатся повторяющиеся значения. Выберите по крайней мере один столбец, содержащий только уникальные значения.»

То есть для того, чтобы установить связь между таблицами, один из связывающих столбцов должен содержать только уникальные, не повторяющиеся значения. К примеру, цена у нескольких продуктов может быть одинаковой (повторяться), поэтому использовать эти столбцы для создания связи между таблицами не получится. А вот «КодПродукта» в t_products содержит только уникальные значения, поэтому мы и смогли использовать его для создания связи.

Таблицы, содержащие столбцы с уникальными значениями, по которым устанавливается связывание, называются «таблицами поиска» (lookup tables).

Ниже представлена сводная таблица на основе данных таблицы t_sales.

Теперь, после того как мы установили связь между таблицами t_sales и t_products, попробуем в поле Строки сводной таблицы вместо столбцац КодПродукта поставить столбец АнглийскоеНазваниеМодели из таблицы t_products.

Как видим всё работает. Теперь мы можем комбинировать данные из обоих таблиц в одной сводной таблице!!

Как это работает

Давайте рассмотрим как работает связь между таблицами, на примере ячейки данных следующей сводной таблицы:

Прежде всего фильтр Цвет=»Red» применён к таблице t_products.

Далее, коды продуктов соответствующие цвету «Red» через установленную связь, из таблицы поиска (t_products) передаются основной таблице (t_sales), которая на основании полученных данных применяет фильтры к столбцу КодПродукта.

ВАЖНО!

Фильтры, применённые к таблице поиска передаются через установленную связь основной таблице. 

Однако, фильтры применённые к основной таблице, не передаются таблице поиска. 

Функция CALCULATE () и связанные таблицы

Давайте создадим ещё одну связь между таблицами. Свяжем таблицу t_sales с таблицей t_clients.

В таблице t_sales, в столбце КоличествоДетейНаПопечении, имеется информация о том сколько отпрысков находятся на попечении каждого клиента. Создадим меру, которая бы на основании этих данных, рассчитывала сумму продаж клиентам с детьми:

                     [ПродажиРодителям]=
                     CALCULATE([ИтогоПродаж],
                     t_clients[КоличествоДетейНаПопечении]>0)

Как Вы надеюсь поняли из вышеприведённого примера, при работе со связанными таблицами фильтр-аргументы функции CALCULATE() можно применять и к таблицам поиска

Создать связанную таблицу через VBA

sgkorolew

Дата: Четверг, 31.05.2018, 23:02 |
Сообщение № 1

Группа: Проверенные

Ранг: Форумчанин

Сообщений: 107


Репутация:

0

±

Замечаний:
0% ±


Excel 2010

Добрый вечер!
Подскажите, пожалуйста, как выполнить команду «Создать связанную таблицу для связи с источником данных» через VBA.
В просторах интернета нашел вот это:
[vba]

Код

DoCmd.RunCommand acCmdImportAttachAccess

[/vba]
Но не понял в каком месте нужно прописать путь к файлу.

 

Ответить

Gustav

Дата: Пятница, 01.06.2018, 11:42 |
Сообщение № 2

Группа: Друзья

Ранг: Старожил

Сообщений: 2398


Репутация:

986

±

Замечаний:
0% ±


начинал с Excel 4.0, видел 2.1

Мне кажется, что Вам больше подойдет команда DoCmd.TransferDatabase.


МОИ: Ник, Tip box: 41001663842605

 

Ответить

sgkorolew

Дата: Пятница, 01.06.2018, 18:42 |
Сообщение № 3

Группа: Проверенные

Ранг: Форумчанин

Сообщений: 107


Репутация:

0

±

Замечаний:
0% ±


Excel 2010

Gustav, то что надо.
Спасибо!

 

Ответить

  • Функция Excel VBA Join

Функция Excel VBA Join

Функция VBA JOIN используется для объединения массива подстрок с указанным разделителем. Так же, как само слово означает, что оно должно соединить две или более строки. Теперь вот несколько уловов с этим. Строки находятся в массиве, и он также использует разделитель в качестве функции сцепления. Но разделитель для функции конкатенации может быть разным для любых двух строк, потому что мы должны предоставить один разделитель между каждыми двумя строками, используя функцию конкатенации. Но в Join в VBA нам нужно указывать разделитель только один раз. Этот разделитель используется для каждой присоединяемой строки. Но этот параметр также необязателен. Так что же происходит, когда мы не предоставляем разделитель для функции? Когда мы не предоставляем разделитель для функции, он по умолчанию принимает «пробел» в качестве разделителя.

Синтаксис функции соединения в Excel VBA

Функция соединения имеет следующий синтаксис в Excel VBA:

Теперь давайте разберемся с аргументами функции VBA Join,

  • Source Array: Это массив или набор строк, которые мы хотим объединить.
  • Разделитель: это разделитель или символ, который мы используем для различения одной строки в другой. Разделитель может быть пробелом или запятой, точкой или любым символом с нашего компьютера.

Выходные данные, возвращаемые этой функцией, являются строкой.

Как использовать функцию Excel VBA Join?

Мы научимся использовать функцию соединения VBA с несколькими примерами в Excel.

Вы можете скачать этот VBA Присоединиться к шаблону Excel здесь — VBA Присоединиться к шаблону Excel

Excel VBA Join — Пример # 1

Во-первых, давайте начнем с основного примера. У нас есть путь к файлу, хранящемуся в разных ячейках нашего листа на листе 1. Нам нужен полный путь к этому местоположению в другой ячейке. Путь, который необходимо объединить, заключается в следующем,

Мы хотим путь в ячейке E2. Выполните следующие шаги, чтобы использовать функцию соединения в Excel VBA.

Шаг 1: Перейдите на вкладку разработчика и нажмите Visual Basic, чтобы иметь возможность войти в VB Editor.

Шаг 2: Нажмите на вкладку «Вставка» и вставьте модуль в проект VBA.

Шаг 3: Теперь давайте объявим нашу первую подпроцедуру следующим образом.

Код:

 Sub Example () End Sub 

Шаг 4: Поскольку у нас есть данные, мы можем просто использовать значение свойства range, чтобы присоединиться к пути следующим образом.

Код:

 Sub Example () Диапазон ("E2"). Значение = Конец Sub 

Шаг 5: Используйте функцию Join, чтобы объединить все строки вместе с разделителем как «».

Код:

 Sub Example () Range ("E2"). Value = Join (Массив (Range ("A2"). Value, Range ("B2"). Value, Range ("C2"). Value, Range ("D2") .Value), "") End Sub 

Шаг 6: Запустите приведенный выше код, нажав клавишу F5 или нажав кнопку Play run, и мы получим наш результат в ячейке E2, как показано ниже.

Мы можем видеть, что все четыре строки объединены общим разделителем, который является «».

Excel VBA Join — Пример № 2

Давайте продолжим с практическим примером. На одном листе у меня есть имя ученика, его отметки, а также пропуск или провал. Мы хотим создать отдельную папку с файлами, в которых будет указано, прошел или нет студент или получил оценку. Для этого мы заимствуем некоторые концепции FSO (объекты файловой системы), используя функцию соединения. Ну, данные выглядят так, как показано ниже.

Выполните следующие шаги, чтобы использовать функцию соединения в Excel VBA.

Шаг 1: В том же модуле давайте запустим еще одну подпроцедуру следующим образом.

Код:

 Sub Example2 () End Sub 

Шаг 2: Объявите две переменные как FSO и текстовый поток, который является методом FSO следующим образом.

Код:

 Dim FSO As New Scripting.FileSystemObject Dim St As Scripting.TextStream 

Шаг 3: Теперь давайте объявим еще несколько переменных: одну — как диапазон для хранения строк, а другую — как целое число для столбцов, а другую — как String для хранения значения объединенной строки и пути к папке и одну для создания имен файлов.

Код:

 Dim rw как диапазон Dim res как строка Dim col как целое число Dim FolPath как строка Dim результат как строка 

Шаг 4: Поскольку у нас есть данные на листе 2, давайте сначала активируем лист 2.

Код:

 Worksheets ( "Лист2"). Activate 

Шаг 5: Теперь давайте посчитаем количество столбцов в данных следующим образом:

Код:

 col = Range ("A1"). CurrentRegion.Columns.Count 

Шаг 6: Теперь давайте назначим путь к Folpath с помощью информационной функции ENVIRON следующим образом.

Код:

 FolPath = Environ ("UserProfile") & " Desktop  Result" 

Шаг 7: Теперь давайте проверим, существует ли папка или нет, а затем создадим ее, используя метод FSO следующим образом.

Код:

 Если не FSO.FolderExists (FolPath), то FSO.CreateFolder FolPath 

Шаг 8: Теперь давайте добавим имена, сохраненные с помощью функции смещения, следующим образом.

Код:

 Для каждого диапазона rw In («A2», Range («A1»). End (xlDown)) Result = rw.Offset (0, 1) .Value 

Это откроет файлы с именами одновременно в режиме добавления, где последними будут добавлены новые значения. Мы использовали приведенный выше код, чтобы значение результата присваивалось один за другим.

Шаг 9: Теперь, поскольку функция Join использует одномерный массив, мы будем использовать функцию application.transpose вместе с функцией join, чтобы преобразовать ее в одномерный массив следующим образом.

Код:

 Установите St = FSO.OpenTextFile (FolPath & "" & Result & ".xls", ForAppending, True) res = Join (Application.Transpose (Application.Transpose (rw.Resize (1, col) .Value)), vbTab ) St.WriteLine res 

Почему мы использовали application.transpose? Поскольку в общем случае массив (1-D) должен быть горизонтальным, что означает, что в одной строке много столбцов. Теперь, поскольку у нас в столбце B есть вертикальный диапазон, который является результатом, мы использовали эту функцию транспонирования, чтобы преобразовать ее в одномерный массив. Мы использовали VbTab в качестве разделителя, чтобы значения были в следующих ячейках.

Шаг 10: Перед завершением цикла for закройте файл, а затем завершите цикл for следующим образом.

Общий код выглядит так, как показано ниже.

Код:

 Sub Example2 () Dim FSO As New Scripting.FileSystemObject Dim St As Scripting.TextStream Dim rw Как диапазон Dim res Как строка Dim col Как целое число Dim FolPath Как строка Dim Результат как строка строк ("Sheet2"). Активировать col = Range (" A1 "). CurrentRegion.Columns.Count FolPath = Environ (" UserProfile ") &"  Desktop  Result ", если не FSO.FolderExists (FolPath), то FSO.CreateFolder FolPath для каждой строки в диапазоне (" A2 ", Range (" A1 "). End (xlDown)) Result = rw.Offset (0, 1) .Value Set St = FSO.OpenTextFile (FolPath &"  "& Result &" .xls ", ForAppending, True) res = Join (приложение .Transpose (Application.Transpose (rw.Resize (1, col) .Value)), vbTab) St.WriteLine res St.Закрыть следующий rw End Sub 

Шаг 11: Теперь давайте запустим приведенный выше код, нажав клавишу F5, и мы увидим на нашем рабочем столе, что была создана папка с именем Result, как показано ниже.

Шаг 12: Откройте папку, у нас будет три файла: Pass, Fail и Grace.

Если мы откроем какой-либо из файлов, скажем, что мы открываем файл Fail, мы можем увидеть данные об учениках, которые потерпели неудачу.

То, что нужно запомнить

  • Он используется для объединения строкового массива с общим разделителем.
  • Выходные данные, возвращаемые этой функцией, являются String.
  • Это противоположно функции Split в VBA.
  • Если мы не предоставляем разделитель для этой функции, он по умолчанию принимает «пробел» в качестве разделителя.
  • Массив в аргументе должен быть одномерным массивом. Если нет, мы можем использовать обычные методы application.transpose, как описано в Примере 2.

Рекомендуемые статьи

Это руководство по функции присоединения VBA. Здесь мы обсудим, как использовать функцию соединения в Excel с использованием кода VBA, а также с практическими примерами и загружаемым шаблоном Excel. Вы также можете просмотреть наши другие предлагаемые статьи —

  1. Функция даты Excel
  2. Конкатенация строк в Excel
  3. Приложения VBA Union
  4. Конкатенация столбцов Excel

Понравилась статья? Поделить с друзьями:
  • Связать рисунки в word 2010
  • Связать разные листы в книге в excel
  • Связать несколько списков excel
  • Связать лист с другими листом в excel
  • Связать значения списков excel