Страницы: 1
RSS
Функция Format. Excel 2016. Формат даты при работе с PivotTable
 

Доброго времени суток, уважаемые.

Очень надеюсь, что знающие сочтут «задачку» интересной и попробуют найти решение или наоборот простой и «направят в нужное направление».

Предыстория: код начинал писать на 2010 Excel и этой проблемы не наблюдал. После установки 2016 офиса не могу разобраться с казалось бы простой вещью - форматом даты. Функция FORMAT работает не логично.

Имеется:

Таблица, данные в которую тянутся из SQL. Столбец с датой загружается в виде dd.mm.yyyy, но EXCELем воспринимается как текст. Чтобы это исправить (нужно сортировать именно как дату) применил .TextToColumns DataType:=xlFixedWidth, FieldInfo:=Array(Array(0, 4), Array(10, 9))

С этой таблицы строится сводная. Дата – одно из отображаемых Field. Отмечу, что в сводной с датами все «ок» и они сортируются и отображаются корректно (dd.mm.yyyy).

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

Код
For Each pItem In Sheets("Сводные").PivotTables("testpivot").PivotFields("Дата").PivotItems
Debug.Print "without format: " + pItem.Name
Debug.Print "   with format: " + VBA.Format(pItem.Name, "dd.mm.yyyy")
Next

И вот часть результата этого кода:

………обрезано……….

without format: 7/11/2018

   with format: 07.11.2018

without format: 7/13/2018

   with format: 13.07.2018

………обрезано……….

Как видно без функции Format в сводной таблице дата хранится в формате mm/dd/yyyy. Но при преобразовании к виду "dd.mm.yyyy" в случае с датой 7/11/2018 (11 июля) получили 07.11.2018 (07 ноября). И тут же 7/13/2018 (13 июля) обработалось нормально 13.07.2018 (13 июля).

А уже из-за этого дальнейшая работа со сводной невозможна. Например, для функции GetPivotData нужно указать дату в том виде, как она отражена на листе ("dd.mm.yyyy").

Прошу подсказать, как все же заставить VBA воспринимать дату корректно. (без костылей типа if dd>12 :) )

Изменено: madzu - 23.07.2018 16:08:40
 
Даты в Excel, как известно, хранятся как (действительные) числа. Функция Format преобразует их в текст в зависимости от второго параметра.
Значение элемента PivotItem - это свойство Value (а не Name). На наших конфигурациях Ваш макрос после замены .Name на .Value выдает идентичные данные.
Отформатируйте, пожалуйста, код в сообщении #1 специальной кнопкой (оформление текста в виде кода) на панели.
Изменено: sokol92 - 23.07.2018 14:55:36
Владимир
 

Цитата
sokol92 написал:
Даты  в Excel, как известно, хранятся как  (действительные) числа. Функция  Format преобразует их в текст в  зависимости от второго параметра.
В теории так и должно быть, но почему даты 07/12/18 и 07/13/18 (43293 и 43294 соответственно) преобразуются по разному.

Может быть что в сводных таблицах "свой подход" к датам?

Цитата
sokol92 написал:
Значение элемента PivotItem - это свойство Value (а не Name). На наших конфигурациях Ваш макрос после замены .Name на .Value выдает идентичные данные.
Пробовал и то и другое - без разницы. А какой у Вас офис?


Цитата
sokol92 написал:
Отформатируйте, пожалуйста, код в сообщении #1 специальной кнопкой (оформление текста в виде кода) на панели.
Готово
Изменено: madzu - 23.07.2018 16:18:52
 
Цитата
madzu написал:
В теории так и должно быть, но почему даты 07/12/18 и 07/13/18 (43293 и 43294 соответственно) преобразуются по разному.
У меня в Вашем файле преобразуются одинаково. Пробовал на конфигурациях от Excel 2007 (ru), Win XP (win-1251) до Excel 2016 (64,en), Win10 (windows-1252).
Когда Вы выдаете pitem.Value, то значение форматируется в соответствии с региональными настройками даты в Windows. Функция Format в Вашем макросе выдает дату как ДД.ММ.ГГГГ независимо от региональных настроек. В #1 есть одна неправильная дата:
Цитата
madzu написал:
with format: 07.11.2018
Перепроверьте! Такой даты в Вашем примере нет.
Владимир
 
Цитата
sokol92 написал: Перепроверьте! Такой даты в Вашем примере нет.
Так в этом то и есть проблема - в итоге я получаю "даты" которых не было изначально :) Я правильно понимаю что у Вас проблема не наблюдается?
Перечитал справку о свойствах PivotItems на msdn
PivotItem.Name - Returns or sets a  String value representing the name of the object.
PivotItem.Value - Returns or sets a  String value that represents the name of the specified item in the PivotTable field.
Лично для себя разницы не вижу.

Но понял что проблема именно в том, что я с PivotTable достаю текст, а не "цифру". Наверное, нужно копать в сторону настроек и формата даты в системе (екселе).
Изменено: madzu - 24.07.2018 08:54:28
 
Посмотрел повнимательнее - у Вас в указанной сводной таблице "застряли" даты с прошлых обновлений (всего их 368). Excel младших версий их не показывает.
Debug.Print имеет ограничения на объем выводимой информации и в Вашем макросе мы видим только "хвост" от выдачи.
Но сути вопроса, озаглавленного в теме, это не меняет.
Код
MsgBox Sheets("Сводные").PivotTables("testpivot").PivotFields("Дата").PivotItems.Count
Изменено: sokol92 - 23.07.2018 17:03:15
Владимир
 
Цитата
sokol92 написал:
у Вас в указанной сводной таблице "застряли" даты с прошлых обновлений (всего их 368)
Странно, в параметрах сводной настраивал не сохранять данные, удаленные из источника.

Но, я уже приблизился к варианту решения, блягодаря нашему диалогу :)
В параметрах поля "Дата" в сводной нажимаю "Числовой формат" и выбирая иной формат даты, например dd.m.yyyy получаю нужный мне результат. Интересно, все же в чем причина того, что формат по умолчанию "глючит"
 
К сожалению, я ни на одной конфигурации глюков не вижу. Опишите свою конфигурацию, включая региональные настройки полного и краткого формата даты.
Владимир
 
Цитата
sokol92 написал:
всего их 368
Мне кажется у Вас даты в сводной сгруппированы, хотя я это убрал. Из-за этого итемов так много (365 на каджый день года + ">" и "<" какой-то даты) У вас в фильтре в сводной сколько возможных значений для выбора? У меня аналогичный код насчитывает 12 значений.
Допускаю, что проблема именно в моей версии Екселя. так как (изначально писал) до установки 2016 на 2010 все было норм.
Excel2016 (32bit) Win7 SP1 (64bit)
 
Не могу прикрепить изображение. Если Вас не затруднит, можете прикрепить скрин как выглядит окошко Immediate после выполнения кода у Вас? Благодарю
Изменено: madzu - 23.07.2018 17:20:51
 
Вот такой результат я получал у себя при выполнении кода из #1 до изменения "Числового формата":
Скрытый текст
Что интересно, отображение даты в таблице или сводной никак не влияло на результат. Только "числовой формат" в настройках поля сводной влиял.
Вот такой результат когда поставил формат dd.mm.yy:
Скрытый текст
 
Изменено: madzu - 23.07.2018 17:35:11
 
Цитата
madzu написал:
У меня аналогичный код насчитывает 12 значений.
Да, у меня теперь тоже (если не экспериментировать :) ). Я ошибся, когда приспосабливал к английской версии Windows.
Остается лишь загадка с Вашими региональными настройками (Язык и региональные стандарты).
В ваших листингах из предыдущего сообщения криминала я не Вижу.
Изменено: sokol92 - 23.07.2018 17:40:37
Владимир
 
Может кому понадобится (мои настройки формата даты в системе):

Скрытый текст
 
Изменено: madzu - 23.07.2018 17:45:17
 
Цитата
madzu написал:
поставил формат dd.mm.yy
Вы точно этот формат выставляли, а не ДД.ММ.ГГ ?
Владимир
 
Цитата
sokol92 написал:
Вы точно этот формат выставляли, а не ДД.ММ.ГГ ?
В екселе формат вообще задавался цифрами:
Скрытый текст
 
Изменено: madzu - 23.07.2018 17:47:53
 
Через пункт "(все форматы)" Вы всегда можете посмотреть на реальный формат ячейки (локализованный). Какой он у Вас?
Владимир
 
Цитата
sokol92 написал:
Какой он у Вас?
Был по умолчанию, глючит:
Скрытый текст

Поменял на, стало как нужно было:
Скрытый текст
 
Изменено: madzu - 23.07.2018 18:07:16
 
Одна странность осталась: даты выводятся в соответствии с их внутренним числовым форматом, а не локализованным. Если будет возможность, сделайте на Вашей конфигурации в новой книге этот же пример "от нуля" и поделитесь результатами.
Изменено: sokol92 - 23.07.2018 18:28:05
Владимир
 
Цитата
sokol92 написал:
сделайте на Вашей конфигурации в новой книге этот же пример "от нуля"
Можете считать что в #1 и есть такой пример. Проблема наблюдается на другой книге с личной информацией. Как рекомендовано в правилах, я ее не стал выкладывать, и для примера создал новую с аналогичными параметрами, но тестовыми данными.
Как я понял у меня сводная таблица игнорирует локальные настройки дат и по умолчанию "думает" в американском формате mm/dd/yyyy. Так как PivotItem.Value (как и PivotItem.Name) возвращают String, то я и вижу текст сформированый из даты, где первым идет месяц, а потом день.
А вот уже функция Format "наша" :). Она если видит 07/11/2018 (напомню, для Format это уже текст), то не знает что из этого месяц, а что день и старается на наш манер первое число записать как день, а второе как месяц. Если же это невозможно - меняет их местами.


Только после изменения формата в параметрах поля - и сводная и функция начали одинаково соображать)
Изменено: madzu - 23.07.2018 19:10:34
 
Да, согласен с Вашим объяснением. C PivotItem.Value я Вас невольно ввел в заблуждение (не проверив). В Вашем макросе можно попробовать получить "истинное" значение как
Код
Debug.Print pitem.LabelRange.Value
Вообще, при работе с .Value (.Name) нужно учитывать, что пользователь таблицы может переименовать любое значение из области столбцов (строк). Например, измените прямо в сводной таблице дату "27.06.2018" на "мой день рождения". При последующих обновлениях Вы увидите новый текст. Исходное значение можно посмотреть в .SourceName (локализованное) и в .SourceNameStandard (не локализованное).
Итак, сводная таблица (а точнее, кэш) хранит "истинные" значения всех полей, а не их текстовые представления. Свойства PivotItem.Value (.Name, .Caption) возвращают эти значения в виде текста, учитывая для дат числовой формат.
Почему на Вашем компьютере этот текст не локализован - загадка.
Владимир
Страницы: 1
Наверх