Имя: Пароль:
1C
 
Проблема 1904 года при загрузке из Excel в 1С методом ТабличныйДокумент.Прочитать
0 Гений 1С
 
гуру
29.07.20
14:56
Судя по этому манулу, в Excel дата может быть и в формате с 1900 и в формате с 1904:
https://docs.microsoft.com/ru-ru/office/troubleshoot/excel/1900-and-1904-date-system

1С это как-то учитывает при вызове метода:

ТабличныйДокумент.Прочитать(ИмяФайлаСервер, СпособЧтенияЗначенийТабличногоДокумента.Значение)

Получается, что 2020-й года считывается в базу как 2016 при таком способе загрузки. Т.е. я реально на руках имею такой файл.

Есть ли какой-то способ (кроме OLE) определить, нужно ли делать сдвиг дат на 4 года вперед?
1 Гений 1С
 
гуру
29.07.20
15:07
Я написал конвертор, но проблема в том, что заранее не знаю, какой формат у книги..
Если поставщик поменяет формат книги (пофиксит), у пользователя полезет 2024 год:
&НаСервере
Процедура ЗаполнитьДатыВСтроке(новСтр, подСтр, Источник, Приемник)
    Если ТипЗнч(подстр[Источник]) = Тип("Число") Тогда
        //новСтр[Приемник] = Дата(1904,1,1) + (Цел(подстр[Источник]))*60*60*24;
        ВычДата = '190001010000' + (Цел(подстр[Источник]))*60*60*24;
    Иначе
        ВычДата = Дата(подстр[Источник]);
    КонецЕсли;
    
    //В этих книгах дата с 1904 года, поэтому добавляем 4 года:
    //https://docs.microsoft.com/ru-ru/office/troubleshoot/excel/1900-and-1904-date-system
    новСтр[Приемник] = ДобавитьМесяц(ВычДата, 12*4)
    
КонецПроцедуры
2 mikecool
 
29.07.20
15:09
не знаю о такой проблеме
3 mikecool
 
29.07.20
15:10
ждем инфы от владельца мегапрайса, у него то точно такие проблемы решены
4 Гений 1С
 
гуру
29.07.20
15:17
(3) Думаешь он читает через кривое 1с-ное СпособЧтенияЗначенийТабличногоДокумента.Значение?
Думаю у него через взрослое Excel.Application.
Кстати, я знаю клиента, который внедрял мегапрайс, я тогда там фикси работал.
5 Гений 1С
 
гуру
29.07.20
15:18
(2) вот и 1с не знает о такой проблеме и сообщить ей никак нельзя. Я проверил на партнерском - глушняк по 1900 и по 1904 тоже.
6 acht
 
29.07.20
15:20
(5) > и сообщить ей никак нельзя.
Зарегать как ошибку? Да ну, ерунда какая-то.
7 acht
 
29.07.20
15:23
Мой гений дарит вам:

Читаешь документ два раза - как значения и как текст. Берешь одну известную ячейку, форматируешь значение / парсишь текст, сравниваешь.
Количество форматов дат ограничено.
8 Гений 1С
 
гуру
29.07.20
15:32
(7) да, я думал о таком варианте. но уж больно гиморно.
9 Fragster
 
гуру
29.07.20
15:34
читай запросом через ВИД/адодб
10 Гений 1С
 
гуру
29.07.20
15:35
(9) да ладно, я клиенту добавил 4 года, вопрос на будущее. Как то ненадежно получается чтение через ТабличныйДокумент.Прочитать(..., СпособЧтенияЗначенийТабличногоДокумента.Значение)
11 Полован
 
29.07.20
15:37
(9) Там тоже свои приколюхи есть форматами :)
12 hhhh
 
29.07.20
15:42
(10) СпособЧтенияЗначенийТабличногоДокумента вообще даты криво копирует. И Значение и Текст
13 mikecool
 
29.07.20
15:43
(4) он еще взрослее - для чтения использует питон
14 Гений 1С
 
гуру
29.07.20
17:25
(13) Самое обидное, что 1С не узнает, что есть такой косяк в загрузке из Excel и будет самодовольной по этому вопрсоу.
15 acht
 
29.07.20
17:27
(14) Конечно не узнает, если ей не сказать. Пусть это будут твоим секретом. В наследство, опять-таки передашь.
16 Сияющий в темноте
 
29.07.20
23:12
когда дату Excel читаешь через Ole,то там честный Double,который дата в vbscript и по граблям не ходим.
ну а у Excel старых версий есть поле,которое позволяет получить тип системы дат.
но для этого,опять же,ole придется использовать.
поэтому,если писать даты строкой,то грабли останутся в стороне.
17 Гений 1С
 
гуру
30.07.20
10:55
(15) И как мне ей передать, если 1С анально огорожена от разработчиков?
(16) О том и спич.
18 Гость из Мариуполя
 
гуру
30.07.20
15:14
(16) у новых наоборот, мне кажется, еще легче.
Точнее для *.xlsx (если распаковать  в *.xml), то там четко просто прям глазками в workbook.xml виден у реквизита  workbookPr атрибут date1904=1,
Виден только в том случае если тип системы дат 1904.
Если же тип системы дат 1900 (в винде по умолчанию) то атрибута date1904 чаще всего НЕТ вообще, потому что по умолчанию = 0.

т.е. без офиса, безо всяких OLE, без заранее известной (как в (7) предлагается) ячейки, просто тупо распаковать xlsx и глянуть что там в workbook.xml->workbookPr
единственная заморочка - распаковать  в *.xml и потом не забыть почистить за собой.

собственно говоря, вот:
https://imageup.ru/img151/3636557/bezymyannyjj10.png.html
19 Гость из Мариуполя
 
гуру
30.07.20
15:42
+ к (18) причем не надо распаковывать весь *.xlsx
достаточно из зип архива вытащить только один workbook.xml
20 Гений 1С
 
гуру
30.07.20
19:26
Финально сделал так (там были ошибки в определении даты с точностью в один день):

Процедура ЗаполнитьДатыВСтроке(новСтр, подСтр, Источник, Приемник)
    Если ТипЗнч(подстр[Источник]) = Тип("Число") Тогда
        //новСтр[Приемник] = Дата(1904,1,1) + (Цел(подстр[Источник]))*60*60*24;
        ВычДата = '190001010000' + (Цел(подстр[Источник]))*60*60*24;
        Добавка = -60*60*24;
    Иначе
        ВычДата = Дата(подстр[Источник]);
        Добавка = 60*60*24;
    КонецЕсли;
    
    //В этих книгах дата с 1904 года, поэтому добавляем 4 года и 1 день:
    //https://docs.microsoft.com/ru-ru/office/troubleshoot/excel/1900-and-1904-date-system
    Если Год(ТекущаяДата()) - Год(ВычДата) > 2 Тогда
        новСтр[Приемник] = ДобавитьМесяц(ВычДата, 12*4) + Добавка;
    КонецЕсли;
    
КонецПроцедуры
Независимо от того, куда вы едете — это в гору и против ветра!