Имя: Пароль:
1C
1С v8
разработка внешней компоненты
0 vasbur
 
23.04.13
07:16
Написал внешнюю компоненту на С++, которая работает с 1С 7.7 и 8.2
Все работает, за исключением одного: никак не могу понять, как вернуть в 1С пустую дату.
Кто-нибудь сталкивался с подобной задачей? Как ее решить?
1 hhhh
 
23.04.13
07:35
а чем отличается пустая от непустой? Непустую возвращаете?
2 vasbur
 
23.04.13
07:36
непустую возвращает правильно.
Пустая дата возвращается как "31.12.1899"
3 Rie
 
23.04.13
07:38
(0) Верни строкой. А 1С пусть сама строку в дату преобразовывает.
4 vasbur
 
23.04.13
07:43
(3) некрасиво это. Хотя и 1с-стайл.
5 Rie
 
23.04.13
07:45
(4) Можно попробовать вернуть VT_EMPTY. Но не знаю, как 1С на это отреагирует.
6 vasbur
 
23.04.13
07:47
(5) VT_EMPTY как раз и преобразуется в '31.12.1899'
7 Ranger_83
 
23.04.13
07:50
(4) тебе шашечки или ехать?
8 hhhh
 
23.04.13
07:50
(6) пустая дата в 1с - это ведь не EMPTY. Это жостко 1-е января 01-го года. Его и возвращай.
9 Rie
 
23.04.13
07:51
(6) А double 0?
10 Rie
 
23.04.13
07:51
(8) Не запихнётся такое в структуру datetime.
11 vasbur
 
23.04.13
07:53
(7) Конечно же, у этой проблемы есть простое неправильное решение.
Проблема в том, что эта компонента будет публичной, поэтому хочется все сделать красиво
12 Rie
 
23.04.13
07:55
(11) Не такое уж и неправильное. Возможность преобразования типов в COM заложена. А 1С-овская Дата - это не VT_DATE, так что ей всё равно искать аналог.
13 vasbur
 
23.04.13
07:56
(12) непустая дата нормально-же возвращается.
14 Рэйв
 
23.04.13
08:00
(0)Не парься и возвращай -1.
в адинесине при таком возврате считай, что вернуло пустую дату
15 Rie
 
23.04.13
08:03
"The date information is represented by whole-number increments, starting with December 30, 1899 midnight as time zero" - http://msdn.microsoft.com/en-us/library/cc237601.aspx
Соответственно, 1С честно преобразует из DATE в Дата. А то, что у Дата в 1С значений дат больше, чем у DATE - ну вот так сложилось...
16 vasbur
 
23.04.13
08:12
(15) Есть еще вариант вызвать из С++ методы 1С и сконструировать правильную одинэсовскую дату. вот только стоит ли ...
17 Rie
 
23.04.13
08:18
(16) Какой именно метод вызывать-то? К стандартным функциям 1С по COM не добраться.
18 vasbur
 
23.04.13
08:19
(17) массив 1С-ный как-то получается вернуть
19 Rie
 
23.04.13
08:22
(19) Сработает ли NewObject для примитивных типов?
20 vasbur
 
23.04.13
08:24
(19) нужно будет попробовать
21 orefkov
 
23.04.13
09:02
А если VT_NULL ?
22 vasbur
 
23.04.13
09:12
(21) возвращает число 1. неожиденно
23 orefkov
 
23.04.13
09:19
(22)
Неисповедимы пути 1С...
Это в 7 или в 8 ?
В 7ке вообще кривовато работало с COM-значениями.
24 vasbur
 
23.04.13
09:26
(23) Это в 8.2
В 7.7 пока не смотрел даже
25 Кирпич
 
23.04.13
09:33
(0) а как в (8) пробовал уже? 01.01.01
26 vasbur
 
23.04.13
09:36
(25) что такое 01.01.01 в терминах С++?
27 Кирпич
 
23.04.13
09:39
(26) ну пишут что в 1с 01.01.01 считается пустой датой. я правда не знаю. попробуй и всё
28 Кирпич
 
23.04.13
09:42
А если в ВК из 1с передать пустую дату и посмотреть, что 1с передает как пустую дату.
29 vasbur
 
23.04.13
09:45
(28) пустая дата С++ воспринимается 1С как "30,12,1899"
30 Кирпич
 
23.04.13
09:49
ну значит 1с тупо переводит свою пустую дату в com пустую дату.
01.01.01 пробовал?
31 orefkov
 
23.04.13
10:00
Если говорить строго - в COM вообще нет пустой даты, вернее даже сам тип даты в нем не подразумевает наличия "пустой" даты. Так что если делать совсем строго, надо либо передавать дополнительный признак, что дата отсутствует, либо договариваться о том, что определенная дата будет обозначать пустую дату.

Вот для проверки такой код:
VARIANT var;
var.vt = VT_EMPTY;
VariantChangeType(&var, &var, 0, VT_DATE);
SYSTEMTIME tm;
VariantTimeToSystemTime(var.date, &tm);

выдает 30.12.1899
32 Кирпич
 
23.04.13
10:32
вот я в Delphi попробовал так

result := EncodeDate(1,1,1);

   Объект = СоздатьОбъект("datetest.dtest");
   Д = '';    
   З = Объект.Method1(Д);
   Сообщить(З);            
   Если З = Д Тогда  
       Сообщить("Пустая дата");
   Иначе
       Сообщить("неПустая дата");
   КонецЕсли;
   Объект = "";

1с сообщает пустую дату, т.е. " .  .  "
но за пустую дату всё равно не считает :))
33 vasbur
 
23.04.13
12:08
(31) ок, сформулирую вопрос так: "как вернуть в 1С 8.2 дату '0001.01.01'?
34 Кирпич
 
23.04.13
12:15
(33) Либо запиши в переменную -693593 как double и поставь тип VT_DATE
либо используй специальную функцию для кодирования даты
35 orefkov
 
23.04.13
12:20
(33)
В рамках COM - "A variant time is stored as an 8-byte real value (double), representing a date between January 1, 100 and December 31, 9999, inclusive." дату ранее 0100.01.01 не вернуть.

Так что надо выходить за рамки - например, возвращать строкой, или возвращать свой объект со свойствами День/Месяц/Год и преобразовывать уже на стороне 1С.
Лично я совсем "выхожу за рамки" - и в своих ВК притворяюсь обычным объектом 1С, обходя всю эту бодягу с COM'ом.
36 Кирпич
 
23.04.13
12:46
семерка сама кодирует Дата(1,1,1) в вариант как double  -693593 и ставит тип VT_DATE

если ей вернуть такое же значение, то она понимает, что это пустая дата. отображает в Сообщить() как пустую дату " . . ", но если сравнить с другим Дата(1,1,1), то получается не равно.

короче туман и лучше не париться за такую ерунду.
37 vasbur
 
23.04.13
12:58
Короче, будет у меня поле типа "дата, но иногда не дата".
Блин.
38 Rie
 
23.04.13
13:08
(37) При присваивании дате - преобразуется корректно. В чём проблема-то? Ну нет в OLE 1С-овского типа Дата. Накосячил Microsoft :-)
39 vasbur
 
23.04.13
13:11
(38) При сравнении больше-меншье неожиданно будет exeprion
40 Кирпич
 
23.04.13
15:29
А в восьмерке работает нормально

Процедура КнопкаВыполнитьНажатие(Кнопка)
   // Вставить содержимое обработчика.
   
   Объект = Новый COMObject("datetest.dtest");

   П = Дата(1,1,1);  
   
   Г = Объект.Method1(П);

   Если Г = П Тогда  
       Сообщить("Пустая дата");
   Иначе
       Сообщить("неПустая дата");
   КонецЕсли;
   
   Объект = "";    
КонецПроцедуры
41 Кирпич
 
23.04.13
15:30
В семерке тоже работает, но только если

П = Дата(0,0,0);
42 Кирпич
 
23.04.13
15:39
Но автор уже наверное уже у ларька горе заливает.
43 vasbur
 
23.04.13
18:23
(40) Method1(П) как написан?
44 Rie
 
23.04.13
18:26
(43) Ну, возможно, так
HRESULT Method1(COleVariant param, COleVariant *result)
{
   *result = param;
}
:-)
45 Кирпич
 
23.04.13
19:23
(43) В (34) написано, как Method1(П) написан
46 vasbur
 
23.04.13
19:25
(44) точно, там же переменная туда-сюда гоняется.
Это не дает ответ на вопрос "как вернуть пустую дату в 1С, не получив ее предварительно из 1С"
47 Кирпич
 
23.04.13
19:35
(46) ПОВТОРЯЮ ПОСЛЕДНИЙ РАЗ

запиши в переменную (результат твоей функции) значение (-693593) как double и поставь тип VT_DATE

у меня на Delphi так

TVarData(result).VType := varDate;
TVarData(result).varDouble := -693593;

надеюсь ты дотюкаешь как это сделать в Си++.
48 vasbur
 
23.04.13
21:50
(47) Попробовал, в 8.2 и правда пустая дата возвращается.
В 7.7 возвращается какая-то непонятная дата: визуально она пустая, но ПустоеЗначение() от нее равно 0
49 mistеr
 
16.05.13
22:35
А в нативном API есть понятие пустой даты?
50 Maniac
 
16.05.13
22:39
(0) на 8.2 com -компоненты не котируются.
Как только речь зайдет о клиент-сервере. Не говоря уже под линукс.
51 oleg_km
 
16.05.13
22:46
(50) Вовсю использую ком-компоненты, на 8.2, клиент-сервер. Г-нопсевдостандарты 1С у меня не котируются
52 vasbur
 
18.05.13
22:18
(50) зато com под 7.7 шарашит
53 mistеr
 
19.05.13
01:09
(52) Можно ведь делать две версии, COM и нативную, с почти общим исходным кодом.
54 vasbur
 
19.05.13
08:15
(53) это, видимо, следующий этап