<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55
global $wpdb2;
global $failure;
global $file_hist;
///// echo '<H2><b>Старт загрузки</b></H2><br>';
$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
///// echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}
$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
///// echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}
/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
///// echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
///// echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist); ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7]; ////получаем размер файла
$m_mtime_file=$masiv_data_file[9]; ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file
///// echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
///// echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
///// echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);
if ($results)
{ foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));
////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
///// echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
///// echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}
////загружаем данные
$table='vin_history'; // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация // (путь от корня web-сервера)
$delim=';'; // Разделитель полей в CSV файле
$enclosed='"'; // Кавычки для содержимого полей
$escaped='\
😀
меня интересует — этот модуль на delphi Вы сами писали или это от 1С?
Сами конечно. Какой смысл выкладывать модуль от 1с?
Извините что не в тему, но мне тяжеловато работать с Делфями 😥
Есть ли такое же только на С++? (Borland Builder или Visual C++)
На ИТС есть документация и примеры на Си++
Возможно ли использование на FPC+Lazarus?
И еще — было бы неплохо и для v77 аналогичный ВК-класс сделать.
Возможно ли использование ?
И еще — было бы неплохо и для v77 аналогичный ВК-класс сделать.
Для FPC+Lazarus надо допиливать. Сходу не заработало, но заработает.
Для v77 можно сделать, но вроде как уже и так хватает.
есть возможность как то передавать не простые данные в ВК, а ссылки на элементы справочников или документов и уже внутри ВК с этими элементами работать?
если можно примерчик небольшой
спасибо заранее
Нету такой возмоности. В NativeAPI такое не предусмотрено.
(8) зачем? для этого 1С есть…
Проверил однако работает! Спасибо!
Компонента на основе этой с полезным функционалом, которого отчасти не хватало в 1С 8.2http://infostart.ru/public/88060/ (запуск процесса, переключение раскладки и др.).
(9) Я так понимаю что не предусмотрен возврат и ссылок на таблицу значений или на какую другую коллекцию значений?
Скажите, пожалуйста, возможно ли с использованием NativeApi организовать поток (Delphi), который будет независимо выполнять определенные действия, и генерить в нужных ситуациях внешнее событие в 1С 8. В моем случае нужно опрашивать весы подключенные к com порту с периодичностью хотя бы раз в секунду и если они подключены при изменении веса отсылать данные в 1С. Обработчик ожидания не устраивает, так как 1С работает однопоточно и очень сильно висит при опросе com порта.
Спасиюо, толковая работа
(14) точно можно
(9) тот же вопрос, что и в (13) ответьте пожалуйста.
(13) Да
(13) Можно передавать только простые типы данных и вернуть из ВК двоичные данные. Вроде всё пока. Остальное 1С блокирует.
Здравствуйте,
http://infostart.ru/public/88060/ не подходит для самого простого примера. А вообще стоит задача написать внешнюю компоненту для общения с COM портом. и используя ваш пример можно написать данную ВК?
Пробовал по примеру писать NativeAPI компоненту, но почему то не воспринимает функции, пишет «Поле объекта не обнаружено (Hello)». Или v8napi.pas от
есть конечно примеры на CPP, но времени разбирать с Visual большого нет.
(20) видимо где то чего то неправильно понаписал. У всех работает нормально, жалоб не было.
есть вопрос. Заключается он в том, что в ВК на технологии СОМ обработка ошибок во ВК производилась функцией RaiseLastOSError и все работает ОК, а вот теперь вроде сделал на Native API, и при вызове данной функции ВК, 1Ска закрывается (вылетает). какие методы есть решения? не подскажете.
(23) mur611,
V8.AddError(wcode: word; const source: PWideChar;
const descr: PWideChar;
scode: integer): boolean;
см. документацию от 1С
есть вопрос, как вернуть массив? входные параметры функции — число, строка, а вот вернуть функция должна массив или olevariant, каа быть?
(25) igor_kav, только генерировать строку с внутренним представлением любой коллекции (массив, структура, список значений, и т.д.), а в 1С уже преобразуешь с помощью ЗначениеИзСтрокиВнутр(). К сожалению, я не смог найти ни одного внятного описания структуры внутреннего представления ТаблицыЗначений, а по всем остальным коллекциям формат довольно простой.
Сам на основе данного шаблона делал компоненту для внутреннего использования, с возвратом из функции массива. Если нужно, напиши, кину пример кода.
Вот как раз и пример со структурой, у массива формат еще проще:
Показать
было бы здорово готовый код глянуть. скиньте, пожалуйста, на мыло igor_kav@mail.ru
спасибо!
спасибо! пока писал коммент, Вы уже выложили.
а как быть с многомерным массивом?
Кхм, понятия не имею. Честно говоря, ни разу за всю практику не сталкивался с необходимостью использования многомерных массивов. Но, если размышлять логически, то сам формат представления для массива таков:
где ОписаниеКлючаN и ОписаниеЗначенияN:
Логично предположить, что если описание тпа подставить Массив, и а в значение — внутреннюю строку вложенного массива, то должно получиться то, что нужно.
Но надо проверять, конечно. Попозже гляну.
Извиняюсь, как говориться, поспешишь — людей насмешишь. В предыдущем сообщении спутал понятия массивы и структуры. Массив разобрал, еще проще выходит:
И действительно, для вложенных массивов достаточно в описание значения вместо строки {ОписаниеТипа,Значение} передать строку {ОписаниеМассива}, сформированную аналогично.
Spi1y, Спасибо! ОЧЕНЬ помогли!
Всегда пожалуйста 🙂
Пару функций удалось сделать и использовать в 1С, но написал третью функцию в dll… при попытке использования в 1с именно этой третьей функции, 1с вылетает с ошибкой «Программа 1Сv8 не работает Возникшая проблема привела к прекращению работы программы. бла-бла». Самое интересное, что для тестирования создал проект VLC на delphi, поместил в него код функции. В VLC-проекте ФУНКЦИЯ РАБОТАЕТ!
Какие есть варианты решения?
(35) igor_kav, покажи код
поставил исключение в процедуре _CallAsFunc и получил ошибку:
Внешняя компонента : Invalid pointer operation.
Ошибка! {Форма.Форма.Форма(473)}: Ошибка при вызове метода контекста (ПолучитьМоиДанные): Ошибка внешней компоненты
(38) ну вроде всё правильно. смотри в отладчике.
а как отладить dll?
Прочитал, что СКОРЕЕ ВСЕГО УТЕЧКА ПАМЯТИ ИЗ-ЗА ИСПОЛЬЗОВАНИЯ STRING, но как решить ума не приложу…
Кто сталкивался, ПОМОГИТЕ!
(41) от утечки памяти такого не бывает. такое бывает когда используешь указатель, который ни на что не указывает.
выдает ошибку External exception C000001D на строке:
Но только в DLL, в EXE все нормально работает. В чем же все-таки причина?
Можно ли передать функции параметр типа ТаблицаЗначений или XDTO пакет и как его потом в delphi разобрать?
(43) причина в ошибке. надо смотреть в отладчике. вышли мне исходники, я гляну. у тебя delphi 7?
(45) спасибо! 🙂 ошибку нашел! все, как всегда, было банально просто. RIO не освобождал.
Спасибо за проделанную работу, очень нужную вещь ВК NativeAPI на Delphi создали.
(46) да наздоровье
Александр, из компоненты (*в вашей реализации) есть возможность обращаться к методам интерфейса 1С?
Объясните мне — зачем нужна структура «ТV8ObjectRec» ?
На сервере x64 не работает, к сожалению. Ковыряю-ковыряю код, не пойму, в чём дело.
Я на 64 не пробовал. Может так заработает(см. прикрепленный файл)
(51) это из оригинальных исходников от Александра Соломатина? Нет, тоже не получается.
Ну у меня нету сервера 64. пока ничем не могу помочь.
(52) vladon, а на клиенте 64 работает?
(52) vladon, а как не работает? в чем компилировалось?
(54) клиента 64 же не существует.
компилировалось Delphi XE2 и Delphi XE3.
(56) vladon, ну и как не работает то. в чем это не работает проявляется?
(57) вот здесь лежит архив со всеми исходниками:http://narod.ru/disk/61615376001.5ca45c99a6ebdc7d919aa57124f0aa7b/SocketNative.zip.html
в каталоге 1С есть .dt-шник, это база, где в общий макет залиты dll-ки с манифестом в зипе, dll-ки откомпилены delphi xe3, в любом случае все исходники там же
и есть обработка, которая запускает подключение компоненты на сервере
так вот, на 32-бит сервере компонента подключается — всё нормально отрабатывает
на 64-бит сервере при нажатии кнопки «Подключить компоненту» сервер долго-долго думает, а потом клиент вылетает с сообщением, что сервер принудительно закрыл подключение.
в любом случае, если есть возможность, попробуйте сами.
(58) vladon, попробуй такой вариант. у меня вроде работает. на сервере не проверял(нету у меня). проверял тестовой программой, которая загружает dll и читает список методов и свойств ВК. старая твоя ВК не грузилась, теперь стала грузиться. в архиве вариант модуля v8napi.pas. отпишись заработало или нет.
файл
(60) огромное спасибо, работает.
какова лицензия на исходный код? возможно ли его использование в проектах под лицензией GPL v2/3?
Да используйте где хотите.
(63) не сочтите за наглость, но, так сказать, во избежание возможных недоразумений, можно при следующем обновлении в программных модулях указать тип лицензии на исходный код? например, Apache 2.0 (наиболее предпочтительная и либеральная), X11, или Modified BSD (неограниченное использование). или двойную лицензию GPL v2 и GPL v3 (на выбор пользователя).
хотим тут один небольшой проектик замутить на базе модуля для FreePascal под лицензией GPL v2, в целях экономии времени на рутину хотим использовать Ваш модуль 😉
спасибо.
Мегаценная вещь, спасибо автору большое! Но возник вопрос, мне очень нужно сделать так, чтобы во время работы какой либо одной функции вызванной по nativeapi из 1С, произошла передача данных (к примеру установка свойства формы или генерация внешенего события с передачей данных в 1С). Например:
//процедура вызываемая из 1С
function TMyClass.SleepFunc(RetValue: PV8Variant; Params: PV8ParamArray; const ParamCount: integer; var v8:TV8AddInDefBase): boolean;
var
ms: Integer;
begin
ms := V8AsInt(@Params[1]); // к примеру 100.000
//тут хочу вызвать исключение в 1С и передать в него строку «Привет я пошел спать!» или как-то иначе
sleep(ms);
//допустим тут еще раз хочу вызвать исключение
//или установить свойство заголовка на форме или переменной модуля 1С. «Привет я проснулся!»
result := True; //завершается вызванная функция
end;
После некоторых исследований, было установлено, что к примеру если вызвать во время работы функции sleep (или любой другой) функцию, например, вызова внешнего события, то оно генерируется не в то время, где я вызываю ExternalEvent, а только по выходу из основной функции. То есть у меня никак не получается передавать в 1С, например строку промежуточного результата работы функции во время ее работы. Все уходит в 1С только по выходу из нее. Как решить подобную задачу?
в модуле для FPC не нашёл функцию V8SetPWideChar ( возврат в 1С строки, представленной в FPC типом PWideChar )
дописал. может, кому, пригодится:
Показать
в модуле для FPC ошибка в function _GetParamDefValue, вызывающая падение в случае, если параметры по умолчанию не заданы, а 1с видит, что методу передано меньше параметров и пытается запросить параметр по умолчанию
правильный вариант кода:
Показать
(67) andrewks, Спасибо. Исправлю.
что-то не ясен момент: в описании технологии Native API сказано, что BLOB (Двоичные данные) могут только возвращаться из компоненты в 1С, про передачу BLOB из 1С в компоненту ничего не сказано. при попытке передать ДвоичныеДанные в параметре метода 1С ругается на неверный параметр (до компоненты даже дело не доходит).
однако в Вашем модуле есть функция по получению BLOB V8AsBlob(). У Вас получилось передать ДвоичныеДанные в компоненту? не поделитесь рецептом?
(69) andrewks, я не помню, что пробовал. ну если не дает, то значит нельзя. А V8AsBlob() наверное на всякий случай сделал.
А в 81 работает?
(71) fixin, в 8.1 нет NativeAPI
Раз уж добавили поддержку Lazarus, может попробуем и под Linux скомпилить?
Вот тут есть готовая виртуальная машина с установленным Lazarus , попробовал в нем скомпилить выложенную демку, но она не подключается в контексте сервера 1С под x64 Ubuntu. Есть мысли? Спасибо!
Мыслей нет. А что нибудь другое подключается в контексте сервера 1С под x64 Ubuntu?
(73) UncleVader, там же написано, что под Android
(74) У меня нет к сожалению ни одной ВК под linux, поэтому трудно сказать, дал бы кто попробовать…
(75) andrewks, ну и что, главное что стоит настроенный Lazarus и компилит, в т.ч. и приложенный тут пример ВК
(76) UncleVader, я к тому, что если у Вас есть доступ к серваку с убунтой х64, то, может, стоит скомпилить прямо на нём? у меня на ноуте стоит убунта, но она там х32
(77) andrewks, Чтоб на нем скомпилить туда надо поставить Lazarus, а для меня это китайская грамота ((
Во вложении скомпиленная в упомянутой (73) системе, попробуйте может у Вас подключится
Поставил 64 Ubuntu, на него Lazarus, скомпилил пример — на сервере не подключается ((
удалено
Почему когда я создаю поток у меня вылетает ошибка? В чем проблема? Код в прекрепленных файлах
Ну ты в отладчике посмотри где глючит. А ProcessMessages тебе зачем? Поставь вместо ProcessMessages sleep(0) для начала.
(82)Я так и со слипом пробовал бесполезно! Попробуй у себя проверить мой код.
Выдает ошибку и вылетает 1с именно когда запускается поток ReadThread
(83) SerG_121, видимо, у Вас исключение вылетает. попробуйте в try/except и выводить лог, может, прояснится
(83) SerG_121, Ты создаешь объект в 1с. Выполняешь его метод ОткрытьПорт. В методе ОткрытьПорт создается поток, который использует объект. Но объект после выполнения ОткрытьПорт автоматически убивается, но в потоке к нему есть обращение в Execute. Обращение к несуществующему объекту. Наверное по этому и глючит.
(85)Может подскажешь как реализовать?
А чего надо реализовать?
(87)Спасибо большое все разобрался )
Собрал ВК в Lazarus.
Нашел небольшой глюк: если передать в функцию ФункцияПривет2 пустые строки, то платформа «валится»
Обошел путем добавления условия
перед строкой
в методе V8SetWString
В Linux таки не работает.
Платформа грузит .so, вызывает несколько функций и валится по SIGSEGV.
Вот что успевает вызвать:
[quote]
GetClassNames
GetClassObject
_setMemManager
_GetInfo
[/quote]
После этого падение. Пока причину понять не смог, может быть будут идеи?
(90) Magister, есть идея посмотреть в отладчике. линуксов у меня нету.
(91) Отладчик ловит исключение, и в качестве адреса показывает нулевые адреса. Бред полный 🙂
Ещё немного поразбирался — судя по всему причина в том, что под Linux 1С компилируется с использованием GCC, а у него виртуальная таблица методов в памяти имеет другую структуру.
Получается что «грязный» хак, с помощью которого вообще работает эта библиотека не срабатывает, т.к. TV8ProcRec не соответствует IComponentBase.
Пока что удалось добиться таки вызова RegisterExtensionAs добавлением парочки пустых полей с типом Pointer, но теперь другая проблема — V8MM.AllocMemory() возвращает false…
(89) TamDE, что-то не так в Вашем королевстве.
1. эта функция отвечает за возвращаемые значения, а не за передаваемые
2. L не может быть равно 0
3. у меня падения на пустых строках нет
(92) Magister, а Вы на какой платформе, и на каком дистре лин тестируете?
(94) Ubuntu 12.10 x32, 1C 8.3.2 x32 файловая.
На Windows с тем же релизом 1С всё хорошо.
(95) Magister, немного наблюдений:
в Win 1с вызывает функции в таком порядке:
Initialization
GetClassObject()
_Init()
_setMemManager()
_SetLocale()
_GetInfo()
_RegisterExtensionAs()
…
_Done()
DestroyObject()
Finalization
в Lin:
Initialization
GetClassObject()
_setMemManager()
_GetInfo()
далее — падение до захода в _RegisterExtensionAs()
почему-то в линуксе обходится стороной _Init()
(92) Magister, похоже, проблема с менеджером памяти. только у меня при попытке вызова AllocMemory() — сразу крах. пытаюсь в _setMemManager() вызвать AllocMemory() — в винде успешно, память выделяется, в лин — сразу крах.
что-то с описанием интерфейса, может? соглашение о вызове, думаю, тут ни при чём
А может кто подскажет, можно ли в функцию ВК, написанную по NativeAPI, передавать массив или может структуру? И как это делать? В HasRetVal определил метод, как функцию, в GetNParams задал количество параметров данного метода — 1. Метод называется «Подключить». Если передаю скалярный параметр — все нормально (Компонента.Подключить(1)), а если пытаюсь передать массив или структуру (Компонента.Подключить(Массив)) — выдает ошибку в 1С — неверный аргумент.
(61)Добрый день. Владислав, можете уточнить, что именно заработало? Компонента на 64 битном приложении, компилируется, и работает в 1с, то есть подключается, и выполняет всю свою функциональность? То есть помогло применение модуля из архива SocketNative64.zip? А компилировали Lazarus_ом? Версия компилятора тоже 64, или кросс-компилятором?
Блин, я никак не пойму, при попытке выделить память падает все… Если не сложно подскажите где что еще можно подправить, с учетом архитектуры. (Все на винде пока что)… Спасибо.