Excel массив с датами на vba

Не, Вить, надоедает одно и тоже ежедневно клепать — вот и развлекаюсь как могу

ЗЫ А температура есть, я уже месяц как перманентно болею
С переменным успехом

Не, Вить, надоедает одно и тоже ежедневно клепать — вот и развлекаюсь как могу

ЗЫ А температура есть, я уже месяц как перманентно болею
С переменным успехом Serge_007

Сообщение Не, Вить, надоедает одно и тоже ежедневно клепать — вот и развлекаюсь как могу

ЗЫ А температура есть, я уже месяц как перманентно болею
С переменным успехом Автор — Serge_007
Дата добавления — 29.07.2013 в 22:07

Источник

Как отфильтровать даты с помощью макросов VBA в Excel

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

Уровень мастерства: Средний

Скачать файл

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

VBA AutoFilters Guide.xlsm (100.5 KB)

Фильтры даты в Excel

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

Мы также можем выбрать из подменю Date Filters. Это позволяет нам фильтровать диапазоны дат, как до, после или между двумя датами. Есть также много вариантов дат в периодах (этот месяц, следующий месяц, последний квартал и т.д.).

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

Фильтры диапазона дат в VBA

Следующий макрос содержит примеры основных фильтров даты. Важно отметить, что значения параметров Criteria заключены в кавычки. Операторы сравнения = <> также включены в кавычки.
Пожалуйста, ознакомьтесь с моей статьей Фильтрация сводной таблицы или среза по самой последней дате или периоду для получения более подробной информации о том, как использовать метод AutoFilter и его параметры.

Вы можете скопировать / вставить приведенный ниже код в VB Editor.

Несколько групп дат

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

Для этих фильтров мы устанавливаем для параметра Operator значение xlFilterValues. Мы используем Criteria2 (не Criteria1), чтобы указать массив элементов с помощью функции Array.

Это специальный массив шаблонов, где первое число — это период времени (год, месяцы, дни и т. Д.). Второе число — последняя дата в диапазоне. Макрос ниже содержит примеры и дальнейшие пояснения.

Динамические даты в периодах

Следующий макрос содержит примеры дат в определенных периодах. Это аналогично выбору предустановленных элементов фильтра из подменю «Фильтры даты».

Для этих фильтров мы устанавливаем параметр Operator равным xlFilterDynamic. Мы устанавливаем Criteria1 в константу, которая представляет параметр периода динамической даты. Константы перечислены ниже.

Вот ссылка на справочную страницу MSDN со списком XlDynamicFilterCriteria. И спасибо Дугу Глэнси из YourSumBuddy за то, что он указал на февральскую опечатку в константе. У него есть несколько полезных советов для параметра Operator в этой статье.

Фильтры и типы данных

Параметры раскрывающегося меню фильтра изменяются в зависимости от типа данных в столбце. У нас есть разные фильтры для текста, чисел, дат и цветов. Это создает МНОГО различных комбинаций операторов и критериев для каждого типа фильтра.

Я создал отдельные статьи для каждого из этих типов фильтров. Статьи содержат пояснения и примеры кода VBA.

Файл в разделе загрузок выше содержит все эти примеры кода в одном месте. Вы можете добавить его в свою личную книгу макросов и использовать макросы в своих проектах.

Пожалуйста, оставьте комментарий ниже с любыми вопросами или предложениями. Спасибо!

Источник

Обычные функции, использующие динамические массивы в Excel

Это перевод главы книги Bill Jelen. Excel Dynamic Arrays Straight to the Point. К содержанию.

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

Использование СЕГОДНЯ() и ПОСЛЕД() для календаря

Допустим, вы используете СЕГОДНЯ() в качестве третьего аргумента функции ПОСЛЕД(). Тогда формула =ПОСЛЕД(6;7;СЕГОДНЯ()) в ячейке А4 вернет массив из 6 строк и 7 столбцов календаря, начинающегося сегодня:

Рис. 74. Использование СЕГОДНЯ() и ПОСЛЕД() для создания динамического календаря на ближайшие шесть недель

Скачать заметку в формате Word или pdf, примеры в формате zip (политикой провайдера запрещено загружать файлы Excel, содержащие код VBA)

Добавьте формулу =ТЕКСТ(A4:G4; » ДДД » ) в ячейку А3 для заголовков дней недели. Обратите внимание, что эта формула разливается на 7 ячеек по горизонтали.

ТДАТА() и ПОСЛЕД() для вывода интервалов времени

Допустим вам нужно получить массив времени с интервалом 5 минут. Одна минута = 1/1440 суток. Поэтому, чтобы формула массива возвращала 5-минутные интервалы, используйте 1/288 в качестве аргумента шаг: =ПОСЛЕД(5;4;ТДАТА();1/288)

Рис. 75. 5-минутные интервалы, отсчитанные от текущего времени

Генерация последовательности букв алфавита

Функция СИМВОЛ() возвращает букву, основанную на коде ASCII. Например, СИМВОЛ(65) вернет A (английскую), а СИМВОЛ(90) – Z. Можно использовать ПОСЛЕД() внутри СИМВОЛ() для генерации последовательности букв, а затем передать этот массив в функцию ОБЪЕДИНИТЬ(), чтобы показать последовательность букв, разделенных дефисом (или любым другим символом). Формула в С3: =ОБЪЕДИНИТЬ( » — » ;ИСТИНА;СИМВОЛ(ПОСЛЕД(B6;1;КОДСИМВ(A6))))

Рис. 76. Генерация последовательных букв с разделителем

Заметим, что ASCII коды принимают значения от 0 до 255, поэтому если ввести строчную я, и указать число букв более 1, функция вернет ошибку, т.к., после я символов ASCII нет.

Несколько наибольших значений диапазона

Если вам нужно вернуть N наибольших значений диапазона, введите требуемое число в G1. Формула в G2 вернет N наибольших чисел, автоматически расширив область результата:

Рис. 77. Возвращает N наибольших значений диапазона

Несколько наименьших значений диапазона с изменением направления вывода

Усложним задачу. Нужно вывести N наименьших значений, но расположить их не по вертикали, а по горизонтали. Первое, что напрашивается, поместить функцию НАИМЕНЬШИЙ() внутрь функции ТРАНСП(): =ТРАНСП((НАИМЕНЬШИЙ(A1:E8;ПОСЛЕД(G1)))).

Рис. 78. Вернуть N наименьших значений в горизонтальном направлении

Посмотрите еще раз на рис. 78. Формула в G2 использует ПОСЛЕД(4) для возврата вертикального массива, который затем превращается в горизонтальный с помощью ТРАНСП(). Так почему же сразу не вернуть горизонтальный массив!? Для этого используйте внутри функцию ПОСЛЕД(1;G1). Эта формула используется в ячейке G3, и она намного короче формулы в G2.

Обратите также внимание, как в ячейках G6, G7 и G11 выводится текст формул. Это делается с помощью функции Ф.ТЕКСТ(). На рис. 78 формула в G6 сама является функцией динамического массива! Функция Ф.ТЕКСТ() ожидала на вход скаляр, а получила массив G2:G3, и разлилась на две ячейки G6 и G7.

Имитация сводной таблицы диапазоном с тремя формулами

Как автор книги Сводные таблицы в Microsoft Excel, я люблю хорошую сводную таблицу. Но менеджер Microsoft проекта динамических диапазонов Джо Макдэйд и MVP Excel Роджер Говьер указали, что три формулы, вполне способны заменить сводную таблицу. При этом не будет потребности в обновлении.

Чтобы построить отчет:

  • Формула в L6: =СОРТ(УНИК(E2:E564)) возвращает уникальный вертикальный список клиентов;
  • M5: =ТРАНСП(СОРТ(УНИК(B2:B564))) предоставляет горизонтальный список продуктов;
  • М6: =СУММЕСЛИМН(G2:G564;E2:E564;L6#;B2:B564;M5#) возвращает сумму продаж по клиенту и продукту.

Когда вы указываете L6# и M5# в аргументах СУММЕСЛИМН, Excel применяет трансляцию, и превращает скаляр в массив нужной размерности для поиска в диапазонах E2:E564 и B2:B564.

Рис. 79. Замена сводной таблицы тремя формулами; чтобы увеличить изображение кликните на нем правой кнопкой мыши и выберите Открыть картинку в новой вкладке

Отображение чисел в двоичном, восьмеричном или шестнадцатеричном виде

Если нужно представить десятичные числа в двоичном, восьмеричном или шестнадцатеричном виде, используйте функции ОСНОВАНИЕ() и ПОСЛЕД(). Формула в А4: =ОСНОВАНИЕ(ПОСЛЕД(B1);<10;2;8;16>;<2;8;4;2>). У функции ОСНОВАНИЕ() три аргумента. Первый число здесь представлен функцией ПОСЛЕД(B1), которая задает массив целых чисел от 1 до 16. Второй – основание, здесь это массив констант <10;2;8;16>. Третий – мин_длина, здесь также массив констант <2;8;4;2>. Работа этой формулы дает пример попарного подъема.

Рис. 80. Генерация двоичных, восьмеричных и шестнадцатеричных чисел

Суммирование длин текстовых строк большого числа ячеек

Используйте формулу =СУММ(ДЛСТР(A2:A12)). Теперь для ее ввода не требуется Ctrl+Shift+Enter.

Рис. 81. Проверка длины ваших твитов

Текст по столбцам

Эта сложная формула разработана Риком Ротстайном. Благодаря использованию функции ПОСЛЕД(), вы можете разбить текстовую строку на слова с использованием лишь одной формулы в В1.

Рис. 82. Функция ПОСЛЕД() облегчает синтаксический анализ

Суммирование всех ВПР

В старом Excel это можно было сделать только с помощью старинной функции ПРОСМОТР(). На самом деле, это была одна из двух причин, по которой пользователи Excel добирались до функции ПРОСМОТР(). С динамическими массивами вы можете использовать ВПР. Вы всё еще будете использовать старую функцию ПРОСМОТР, когда у вас вектор поиска и вектор результатов ориентированы в противоположных направлениях. Единственная формула в Е9 выполняет сначала расчет массива ВПР, а потом суммирует отдельные значения: =СУММ(ВПР(C2:C26;E1:F6;2)). Обратите внимание, что поиск ВПР ведет приблизительно – четвертый аргумент опущен.

Рис. 83. Вычисление всех ВПР и последующее их суммирование

Объединение имени и фамилии

В этом примере используется попарный подъем, который описан в главе 9. Функция получает диапазон имен, один скаляр (пробел) и диапазон фамилий. Первый и последний вектор имеют одинаковый размер. Формула =ПРОПНАЧ(A2:A10& » » &B2:B10) возвращает массив 9×1.

Рис. 84. Объединение имени и фамилии и понижение регистра

Одна формула вместо таблицы данных «что если»

А в этом примере свойство трансляции (см. главу 9) используется для расчета ежемесячных платежей по автокредиту. Диапазон В4:F7 – динамический массив с единственной формулой в В4: =ПЛТ(C9/12;A4:A7;-B3:F3). Первый аргумент – процентная ставка за период. Обратите внимание, что используется простая относительная ссылка, так как не нужно протягивать формулу. Второй аргумент – общее число периодов выплаты по займу – вместо скаляра получает массив А4:А7. Третий аргумент – сумма кредита с обратным знаком – также вместо скаляра получает массив В3:F3. Благодаря трансляции Excel генерит массив из 4 строк и 5 столбцов и передает эти 20 значений в ПЛТ. Обратите внимание, условное форматирование отлично работает с динамическим массивом.

Рис. 85. Одна формула динамического массива в ячейке В4 заменяет таблицу данных

Условное форматирование на основе функции ЗНАК()

Вот еще один пример условного форматирования. Всякий раз, когда я добавляю набор значков «три треугольника» (который явно состоит из двух треугольников и прямоугольника… но я отвлекся), я использую функцию ЗНАК(), чтобы разделить все возможные значения на три группы: больше, равно и меньше. В примере ниже показаны цены закрытия акций компании DJI (ведущего китайского производителя дронов). Используется попарное поднятие для нахождения разницы двух массивов, смещенных один относительно другого на один день. Формула в C3: =ЗНАК(B3:B17-B4:B18) позволяет показать в какую сторону изменилась цена акций.

Рис. 86. Отражение динамики цен закрытия акций

Попарный подъем основан на двух массивах с одинаковым числом строк. В этом примере оба массива находятся в столбце B, но один начинается с B3 (для значения сегодняшнего дня), а другой – с B4 (для значения вчерашнего дня). На рисунке ниже показана формула в C3 в режиме редактирования, так что вы можете видеть два массива.

Рис. 87. Сравнение цен закрытия текущего и предыдущего дней

Использование оператора # для указания на весь массив

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

Рис. 88. Генератор анаграмм с использованием динамических массивов

Этот пример построен на основе нескольких шагов, что не очень эффективно, зато наглядно. В ячейке D2 использован оператор ссылки на массив #. В ячейке D2 массив из A2 сортируется по массиву B2. Поскольку число символов исходного текста в ячейке А1 не известно, размер массивов A2 и B2 также неизвестен. Поэтому ссылка на массив целиком с использованием нотации # очень удобна. В предыдущих версиях Excel пришлось бы использовать функцию СМЕЩ или ИНДЕКС, и в них задавать какое-нибудь большое число, чтобы идти от обратного и определять размер массива.

Чуть подробнее о шагах на этом рисунке. Введите фразу в ячейку А1. В ячейке B1 вычисляется число символов. Это вспомогательная ячейка, которая используется в других формулах. Ячейка A2 применяет подъем с помощью функции ПСТР() для возврата массива отдельных символов фразы. Здесь ПСТР() в качестве второго аргумента – начальная позиция – получает вместо скаляра динамический массив, последовательность целых чисел от 1 до длины строки А1. Третий аргумент – количество знаков =1, так что ПСТР() последовательно возвращает по одному знаку. Ячейки В2 генерирует случайные целые неповторяющиеся числа. Размер массива в В2 такой же, как и в А2. Ячейка D2 сортирует символы массива A2# по числам в B2#. И, наконец, ячейка E2 сцепляет все перетасованные символы из D2 в слово или фразу. Понажимайте F9 для генерации нового набора случайных чисел. Может быть, в ячейке Е2 получится что-то осмысленное.

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

Excel MVP Wyn Hopkins обнаружил, что вы можете использовать ссылку A3# в качестве первой части ссылки на ячейку. Предположим, что у вас есть динамический массив, начинающийся с A3. Формулы других динамических массивов располагаются в B3 и C3. Эти массивы будут расти и сжиматься вместе с A3#, но они не являются частью A3#. Предположим, что вы хотите сослаться на A3:Сn, где n – количество строк в массиве A3#, вы можете использовать ссылку вида A3#:C3, и такой синтаксис будет работать.

Рис. 89. Синтаксис A2#:C2 допустим

Создание элементов календаря

Для любой даты динамические массивы могут вернуть название месяца или последнюю дату месяца. На рисунке ниже в ячейке A2 создан массив дат, соответствующих началу месяцев 2019 г., с использованием формулы =ДАТА(2019;ПОСЛЕД(12);1). Чтобы сгенерировать полные названия месяцев введите в ячейку В2 формулу =ТЕКСТ(A2#; » ММММ » ), либо в ячейку D2 =ТЕКСТ(ДАТА(2019;ПОСЛЕД(12);1); » МММ » ). Чтобы найти даты конца месяцев, используйте в С2 формулу: =КОНМЕСЯЦА(ДАТА(2019;ПОСЛЕД(12);1);0).

Рис. 90. Генерация элементов календаря

Как ни странно, формула =КОНМЕСЯЦА(A2#;0) не работает, и возвращает ошибку #ЗНАЧ! Это общая проблема всех функций, которые изначально были в надстройке Пакет анализа. Формулы, содержащие эти функции, плохо работают с массивами. Разработчики Excel могли бы исправить это, но тогда не будет работать обратная совместимость.

Прогнозирование

Прогнозирование в Excel использует функции ПРЕДСКАЗ() и ПРЕДСКАЗ.ETS(). На рис. 91 в ячейке А146 введены следующие 12 месяцев: =ПОСЛЕД(12;1;145;1). А в ячейке С146 – формула для прогноза продаж: =ПРЕДСКАЗ.ETS(A146#;$B$2:$B$145;$A$2#;1;1). Фактические продажи за прошлые периоды находятся в диапазоне B2:B145. Массив известных периодов введен в ячейке А2: =ПОСЛЕД(144).

Рис. 91. Прогноз на следующие 12 месяцев

Более сложное прогнозирование

В предыдущем примере мы вычислили массив из 12 ячеек, каждая из которых содержала месячный прогноз. В примере ниже этот массив помещается в функцию СУММ, чтобы вернуть прогноз на год. Формула усложняется, и для ее понимания, аргументы в нотации разнесены на отдельные строки:

Рис. 92. Годовой прогноз продаж

Функция ПРЕДСКАЗ.ETS ожидает скаляр, но вместо этого вы передаете ей массив из 12 значений, используя ПОСЛЕД() внутри КОНМЕСЯЦА(). Прогноз основан на фактических данных за 2007–2018 гг., расположенных в ячейках В2:B145. Формулу из E2 можно скопировать в E3:E6.

Возможно, вы спросите: почему нужно пять отдельных формул? Нельзя ли заменить ссылку на год – D2 ссылкой на массив ПОСЛЕД(5;1;2019)? Ответ – нельзя. С двумя вертикальными массивами в одной функции Excel попытается сделать попарный подъем. Но массивы имеют разный размер, поэтому вернется ошибка.

Транспонирование одного массива для предотвращения попарного подъема

Одна из стратегий предотвращения попарного подъема состоит в том, чтобы расположить годы по горизонтали. Одна формула в E3 возвращает массив 12*5:

Рис. 93. Если разместить годы по горизонтали, формула работает

Прогнозирование всех пяти лет в одной формуле

Если вы передадите ПРЕДСКАЗ.ETS в функцию СУММ, то получите суммарный прогноз продаж на 60 месяцев:

Рис. 94. Одна формула возвращает 5-летний прогноз

Данные в строке (столбце) разместить в диапазоне

Предположим, что у вас есть вектор чисел (D1:O1), и вы хотите разместить его в диапазон шириной N столбцов. Введите количество столбцов в D3. Тогда формула =ЕСЛИОШИБКА(ИНДЕКС(E1:AH1;ПОСЛЕД(15;D3));»») вернет диапазон шириной три столбца. Поскольку вы не знаете сколько понадобится строк, и чтобы избежать появления ошибок в нижней части диапазона, вы поместили вашу формулу внутрь функции ЕСЛИОШИБКА().

Рис. 95. Данные из строки в массив из трех столбцов

Использование динамических массивов для зависимой проверки

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

На рисунке ниже элементы первого выпадающего списка отображаются в D4#, благодаря формуле =СОРТ(УНИК(B4:B23)). Проверка в H3 указывает на D4#. Список для второй проверки появляется в E4# благодаря формуле =ФИЛЬТР(A4:A23;B4:B23=H3; » Выберите подкласс » ). Проверка в H5 ссылается на E4# (чтобы создать список, выберите ячейку и пройдите по меню Данные –> Работа с данными –> Проверка данных).

Источник

Adblock
detector

Добрый день!

Подскажите, пожалуйста, такой вопрос. Есть массив Dates(), содержащий даты, заполняется он так:

Код
Dim Dates(1 To 30) As Date

For z = i To j - 1
    If Range("A" & z) > "01.01.2018" Then
       Dates(t) = CDate(Range("A" & z))

        ......

       t = t + 1
    End If
Next z

Проверял — массив заполняется корректными значениями. В ячейках именно даты, можно изменять их формат.
Затем этот массив выводится на график в качестве значений Х для нескольких кривых:

Код
WsG.Activate
    ActiveSheet.Shapes.AddChart.Select
    With ActiveChart
    .ChartType = xlXYScatterSmooth
    .SeriesCollection.NewSeries
    .SeriesCollection(1).Name = "="""KGF""
    .SeriesCollection(1).XValues = Dates
    .SeriesCollection(1).Values = KGF

В итоге на график выводится такая вот ерунда:

Код
=РЯД("KGF";{"1/1/2019";"1/1/2020";"1/1/2021";"1/1/2022";"1/1/2023";"1/1/2024";"1/1/2025";"1/1/2026";"1/1/2027";"1/1/2028";"1/1/2029";"1/1/2030";"1/1/2031";"1/1/2032";...

Эти значения не поддаются форматированию, эксель не воспринимает их как даты.

Пробовал делать массив string, variant, записать в массив text ячейки — ничего не помогало. Куда копать, подскажите, пожалуйста.

I am struggling with a conversion to array in VBA :

Dim list As Range
Set list = Range(series, series.End(xlDown))
list.Select
Dim table() As Variant
Set table = list.value

My understanding is that value returns an array right ? I don’t get why VBA tells me that I "can't assign to array".

My list range looks like that in Excel at the Select, and i aim at having that as an array so that I can format my dates using something like Format(table.Rows(i).Columns(1).value, "yyyy-mm-dd"), looping on my table.

02-Sep-09   1.00
18-Sep-09   1.00
16-Oct-09   1.00
20-Nov-09   1.00
18-Dec-09   1.00
19-Mar-10   1.00
18-Jun-10   1.00

By the way, is it possible to modify the table in place ?

Thanks !

Community's user avatar

asked Nov 30, 2011 at 9:31

BuZz's user avatar

There are a number of problem here.

Problem 1

Set table = list.value

table is not an object so you cannot set it. Try:

table = list.value

Problem 2

series is a VBA keyword associated with charts. Please pick a name, such as MyWSTable, which means nothing to VBA.

Problem 3

A worksheet name is not itself a range. Try:

Dim Table() As Variant
Table = Names("MyWSTable").RefersToRange.Value

Note: you do not need variable list nor do you need to select the range.

Answer to formatting question

The following code will reformat your dates:

For inxrow = 1 To UBound(Table, 1)
  For inxcol = 1 To UBound(Table, 2)
    Table(inxrow, 1) = "ddd d mmm yyyyy"
    Table(inxrow, 2) = ""
  Next
Next

Names("MyWSTable").RefersToRange.NumberFormat = Table

answered Nov 30, 2011 at 10:50

Tony Dallimore's user avatar

Tony DallimoreTony Dallimore

12.3k7 gold badges31 silver badges61 bronze badges

6

You can remove your select: list.Select

To be sure you won’t get errors when assigning a range to an array, you’d better declare your array as a variant:

Dim table As Variant
table = Range(series, series.End(xlDown)).Value

answered Nov 30, 2011 at 10:27

JMax's user avatar

JMaxJMax

25.9k12 gold badges69 silver badges88 bronze badges

That error message is popping because you are using SET to fill the array. Drop the SET and it should load.

You can fil directly the array as follows:

Dim table() As Variant
table=Range(series, series.End(xlDown))

Omiting the Select step makes your code safer and faster.

Unfortunately, you can not load the values directly as dates. You will have to loop throu every item of the array and turn them into date.

answered Nov 30, 2011 at 9:59

CaBieberach's user avatar

CaBieberachCaBieberach

1,7482 gold badges17 silver badges26 bronze badges

You are going about this incorrectly. You should use the NumberFormat property of the range to specify the display format. Something like this:

Range("A:A").NumberFormat = "yyyy-mm-dd"

answered Nov 30, 2011 at 19:31

phoog's user avatar

phoogphoog

41.8k6 gold badges77 silver badges115 bronze badges

Создать массив по возрастанию в диапазоне дат

14.10.2017, 15:46. Показов 3150. Ответов 2


Студворк — интернет-сервис помощи студентам

Доброго времени суток, имеется бесчисленный набор папок в котором есть файлы, имена папок — «01 Сентября 2017», «12 Октября 2017», «07 Февраля 2017» и т. д. Стоит задача создать массив для которого будут формироваться наименования папок по возрастанию в заданном диапазоне дат. Например массив из имен папок от «01 Сентября 2016» до «12 Октября 2017»

Пока смог сделать это, вроде все работает замечательно, даты по возрастанию по дню месяцу, году, но вот границы дней не смог прописать, было две идеи но разбились они как о скалы (

Visual Basic
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
Sub search()
 
Dim arr
Dim arr0
Dim arr1
 
Dim a(0 To 1000) As String
Dim i As Integer
 
Dim objFSO As Object
Dim objFolder As Object
Dim objSubFolder As Object
 
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(ThisWorkbook.Path)
 
i = 0
 
arrMounth = Array("Января", "Февраля", "Марта", "Апреля", "Мая", "Июня", "Июля", "Августа", "Сентября", "Октября", "Ноября", "Декабря")
arr0 = Split("01 Января 2016", " ")
arr1 = Split("12 Октября 2018", " ")
 
For y = CLng(arr0(2)) To CLng(arr1(2))
    For m = 0 To 11
        For Each objSubFolder In objFolder.subfolders
            
            arr = Split(objSubFolder.Name, " ")
            
            If arr(2) = CStr(y) Then
                If arr(1) = arrMounth(m) Then
                    a(i) = objSubFolder.Path
                    i = i + 1
                End If
            End If
            
        Next objSubFolder
    Next m
Next y
 
MsgBox a(3)
 
End Sub

Добавлено через 17 минут
Подумал подумал и добавил еще один цикл, работает конечно, но может быть есть более деликатный способ ?

Visual Basic
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
Dim arr1
 
Dim a(0 To 1000) As String
Dim i As Integer
 
Dim objFSO As Object
Dim objFolder As Object
Dim objSubFolder As Object
 
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFolder = objFSO.GetFolder(ThisWorkbook.Path)
 
i = 0
 
arrMounth = Array("Января", "Февраля", "Марта", "Апреля", "Мая", "Июня", "Июля", "Августа", "Сентября", "Октября", "Ноября", "Декабря")
arrDay = Array("01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31")
arr0 = Split("01 Января 2016", " ")
arr1 = Split("12 Октября 2018", " ")
 
For y = CLng(arr0(2)) To CLng(arr1(2))
    For m = 0 To 11
        For d = 0 To 30
            For Each objSubFolder In objFolder.subfolders
            
                arr = Split(objSubFolder.Name, " ")
                
                If arr(2) = CStr(y) Then
                    If arr(1) = arrMounth(m) Then
                        If arr(0) = arrDay(d) Then
                            a(i) = objSubFolder.Path
                            i = i + 1
                        End If
                    End If
                End If
            
            Next objSubFolder
        Next d
    Next m
Next y
 
MsgBox i
 
End Sub



0



  • #1

Hi there,

I have a date column, and I would like to put all dates within the column into an array. I would then like my code to say If date I am dealing with exists within the array then do nothing, and if it does not exists within the array then do some code, and also add it to the array.

How is it possible to do this ?

Fastest way to copy a worksheet?

Hold down the Ctrl key while dragging tab for Sheet1 to the right. Excel will make a copy of the worksheet.

  • #2

Code:

Sub dhDate()
Dim aDates As Variant
Const dtToLookFor As Date = #7/10/2014# 'July 10th 2014
aDates = Application.Transpose(Range("A1:A" & Range("A" & Rows.Count).End(xlUp).Row).Value)
If UBound(Filter(aDates, dtToLookFor)) > -1 Then
    ' is within the array
Else
    ' do something
    ReDim Preserve aDates(1 To UBound(aDates) + 1)
    aDates(UBound(aDates)) = dtToLookFor
End If
End Sub

  • #3

Code:

Sub dhDate()
Dim aDates As Variant
Const dtToLookFor As Date = #7/10/2014# 'July 10th 2014
aDates = Application.Transpose(Range("A1:A" & Range("A" & Rows.Count).End(xlUp).Row).Value)
If UBound(Filter(aDates, dtToLookFor)) > -1 Then
    ' is within the array
Else
    ' do something
    ReDim Preserve aDates(1 To UBound(aDates) + 1)
    aDates(UBound(aDates)) = dtToLookFor
End If
End Sub

HI Vba Geek,

This is really great code for me, I am just starting to learn array’s in Vba so thanks for your help. I was wondering, if I wanted to do something whereby I create the array via application.getopenfilename multi-select, and I want to know how to add more files into an already exisiting array of files? Here is my attempt…. but code is failing at the If Filter line??

Code:

Sub buildingarryz()
Dim array1 As Variant
Dim array2 As Variant
 
Dim importbook As Workbook
array1 = Application.GetOpenFilename("Excel Files (*.xls), *.xls", _
            Title:="Select Files", MultiSelect:=True)

array2 = Application.GetOpenFilename("Excel Files (*.xls), *.xls", _
            Title:="Select Files", MultiSelect:=True)
 
For i = LBound(array2) To UBound(array2)
   
    
    If Filter(array1, array1(i)) = 1 Then
    MsgBox ("Exists")
    Else: MsgBox ("Don't Exist FOO !")
    ReDim Preserve array1(1 To UBound(array1) + 1)
    array1(UBound(array1)) = importbook
    End If
    Next i
    
    
    

End Sub

  • #4

Actually, I now understand that If filter was failing because I need to do it like ubound(filter(array2, array1(I)) = 1, but when I test this I see that the ubound value is returning 0, even in cases whereby the same file is in both of the two arrays, if this is the case, I would expect ubound(filter(array2, array1(I)) to return the value of 1 ? And then I cant satisfy the condition ubound(filter(array2, array1(I)) = 1, and tell VBA to

Code:

ReDim Preserve array1(1 To UBound(array1) + 1)
    array1(UBound(array1)) = importbook

  • #5

The Filter function accepts only one dimensional arrays (your Multiselect = True in Application.GetOpenFileName satisfies this condition) and if matches are found returns a zero-based array. So if the UBOUND equals zero it means it found one match, if it equals 1 then it found 2 matches and so on).
Be careful that the filter function also matches sub strings within whole words, if you have an array with «Cat», «Matty», «Catty» and you search for «Cat» you will get two matches.

Ottsel

rollis13

  • Solved

I need an Excel-VBA Solution for below mentioned Issue. The solution I am working with is perfect but very slow and nearly kills my PC for IDs more than 500. (and I have 10000+ IDs to process.)

I have Start Date and end date for some IDs,

Data Set 1

ID          Trans_Date     Action
1234567890  01-Jan-2012    Active
1234567890  05-Jan-2012    Dc
1234567890  06-Jan-2012    Active
1234567890  12-Jan-2012     Dc
1234567890  15-Jan-2012    Active

I need to expand the set as below,

Required data set,

ID          Trans_Date  Action
1234567890  01-Jan-12   Active
1234567890  02-Jan-12   Active
1234567890  03-Jan-12   Active
1234567890  04-Jan-12   Active
1234567890  05-Jan-12   DC
1234567890  06-Jan-12   Active
1234567890  07-Jan-12   Active
1234567890  08-Jan-12   Active
1234567890  09-Jan-12   Active
1234567890  10-Jan-12   Active
1234567890  11-Jan-12   Active
1234567890  12-Jan-12   DC
1234567890  13-Jan-12   DC
1234567890  14-Jan-12   DC
1234567890  15-Jan-12   Active

Currently I’m using the formula given below.

(Thanks to Tom Sharpe)

1) Copy the first ID number into D2

(2) Put this formula in D3

=IF(COUNTIF(D$1:D2,D2)<(MAX(IF(A$2:A$20=D2,B$2:B$20))-MIN(IF(A$2:A$20=D2,B$2:B$20))+1),
   D2,
   INDEX($A$2:$A$20, MATCH(0, COUNTIF($D$1:D2, $A$2:$A$20), 0)))
(3) Put this formula in E2:-

=MIN(IF(A$2:A$20=D2,B$2:B$20))+COUNTIF(D$1:D1,D2)
(4) Put this formula in F2:-

=INDEX(C$2:C$20,MATCH(E2,IF(A$2:A$20=D2,B$2:B$20),1))
All these are array formulae and must be entered with CtrlShiftEnter

enter image description here

But even he is suggesting to use VBA. How to do it in VBA ?

Can you help me?

Thank you in advance.

Я новичок в vba, и я пытаюсь получить в vba все даты между двумя датами, например, я вызову функцию с параметрами 01-01-2015 и 15-01-2015, и я получу взамен массив со всеми возможными датами, то есть:

01-01-2015
02-01-2015
03-01-2015
.....
15-01-2015

Я не нашел ответа на форумах, поэтому заранее спасибо за вашу помощь.

5 ответов

Лучший ответ

Вы можете просто преобразовать дату в длинную и сделать цикл (+1) и получить все даты между двумя датами (снова преобразовать это в дату)

Sub Calling()
    Dim test
    test = getDates(#1/25/2015#, #2/5/2015#)
End Sub

Function getDates(ByVal StartDate As Date, ByVal EndDate As Date) As Variant

    Dim varDates()      As Date
    Dim lngDateCounter  As Long

    ReDim varDates(1 To CLng(EndDate) - CLng(StartDate))

    For lngDateCounter = LBound(varDates) To UBound(varDates)
        varDates(lngDateCounter) = CDate(StartDate)
        StartDate = CDate(CDbl(StartDate) + 1)
    Next lngDateCounter

    getDates = varDates

ClearMemory:
    If IsArray(varDates) Then Erase varDates
    lngDateCounter = Empty

End Function


5

Arya
17 Мар 2015 в 15:22

Если вы просто хотите распечатать даты между двумя датами в excel, я предлагаю вам попробовать под кодом.

Sub DateFill()

Dim Start_Date As Date
Dim End_Date As Date
Dim Number_Of_Days As Integer


Start_Date = InputBox(prompt:="Enter the Start Date", Title:="Date Print", Default:="3/1/2013")
End_Date = InputBox(prompt:="Enter the End Date", Title:="Date Print", Default:="3/23/2013")

Range("A1").Value = Start_Date
'Range("B1").Value = End_Date
Range("A1").Select
Number_Of_Days = DateDiff("d", Start_Date, End_Date) ' Return Day

Number_Of_Days = Number_Of_Days + 1
'Range("C1").Formula = "=DATEDIF(A1, B1, ""D"") "


Selection.AutoFill Destination:=Range("A1:A" & Number_Of_Days), Type:=xlFillDefault
    Range("A1:A" & Number_Of_Days).Select


End Sub

Здесь вы избегаете использования Loop, что экономит время выполнения.


0

Swapnil Wankhede
17 Мар 2015 в 17:52

Может быть, это.

Function udf_Array_of_Dates(dtSTART As Date, dtEND As Date, rDATEs As Range)
    Dim dt() As Date, r As Range, d As Long
    For Each r In rDATEs
        If r.Value >= dtSTART And r.Value <= dtEND Then
            d = d + 1
            ReDim Preserve dt(1 To d)
            dt(d) = r.Value
        End If
    Next r
    udf_Array_of_Dates = dt
End Function

Доказательство и синтаксис:

    UDF for array of dates


0

user4039065user4039065
17 Мар 2015 в 15:25

Массив sn, содержащий все даты с 01.01.2015 по 15.01.2015. Msgbox представлен для иллюстрации результата.

Sub M_snb()
  sn = Evaluate("index(text(datevalue(""01-01-2015"")+row(1:" & DateDiff("d", CDate("01-01-2015"), CDate("15-01-2015")) & ")-1,""dd-mm-yyyy""),)")
  MsgBox sn(1, 1) & vbLf & sn(2, 1) & sn(UBound(sn), 1)
End Sub


1

snb
17 Мар 2015 в 16:03

Функция для получения всех дат из заданного диапазона

Function GetDatesRange(dateStart As Date, dateEnd As Date) As Collection
    Dim dates As New Collection
    Dim currentDate As Date
    currentDate = dateStart
    Do While currentDate <= dateEnd
        dates.Add currentDate
        currentDate = DateAdd("d", 1, currentDate)
    Loop
    Set GetDatesRange = dates
End Function

Пример использования

Dim dateStartCell as Range, dateEndCell as Range
Dim allDates as Collection
Dim currentDateSter as Variant
Dim currentDate as Date
Set dateStartCell = ActiveSheet.Cells(3, 3)
Set dateEndCell = ActiveSheet.Cells(3, 6)
Set allDates = GetDatesRange(dateStartCell.Value, dateEndCell.Value)    
For Each currentDateSter In allDates
    currentDate = CDate(currentDateSter)
    'Do something with currentDate
Next currentDateSter


3

cezarypiatek
19 Ноя 2017 в 12:36

Понравилась статья? Поделить с друзьями:
  • Excel массив по номеру столбца
  • Excel масштаб для всех листов
  • Excel массив номер строки
  • Excel масштаб горячие клавиши
  • Excel массив непустых ячеек