Здравствуйте, друзья!
Установил у себя 3CX Phone System. Какие ощущения? Как бесплатный вариант АТС для небольшой компании или для дома даже очень хорош. Можно быстро её настроить, интуитивно всё понятно, но есть ограничения в бесплатной версии.
В бесплатном варианте 4 одновременные коммутации. Некоторые незначительные ограничения,
и среди них одно важное: модуль интеграции с 1С, который они рекламируют отдельно, в 3CX Free Edition не поддерживается.
Если активировать 3CX демонстрационным ключом, заработает модуль 1С, но вместо 4 одновременных коммутаций будет только две.
Да и сам модуль в бесплатном варианте можно установить только на одно рабочее место. Всё это не вписывалось в мои планы.
Но очень загорелось подключить 1С к этой АТС из-за таких нужных удобств:
— звонить не набирая номера, ткнув мышкой в номер контрагента,
— при звонке клиента, до снятия трубки увидеть подсказку: контрагент, вероятное контактное лицо, его долги, свои долги.
— возможность вести журнал звонков в 1С.
Пришлось идти в обход. В файле 3CXDialer.log АТС записывает каждый звонок в реальном времени. Если оперативно эту информацию забирать, то можно, всё чудно и устроить. Ну а в обычном файловом варианте работы 1С с оперативностью может помочь, например, внешняя компонента AddInNative.dll, которая создаёт внешнее событие десять раз в секунду. Но так часто не нужно, поэтому мы частоту слегка уменьшим.
Теперь за дело:
Находим AddInNative.dll, качаем, размещаем её в нужном месте, запускаем из командной строки Regsvr32.exe «C:наше нужное местоAddInNative.dll»
Не забываем в свойствах формы подключить ВнешнееСобытие, ПриОткрытии, ПриЗакрытии.
Перем Таймер, ВремяСтарта, РазмерЛогФайла, НомерТекущейСтроки;
Процедура ВнешнееСобытие(Источник, Событие, Данные)
Если Данные - ВремяСтарта > 600 Тогда
ВремяСтарта = Данные;
Попытка
ПрочитатьЛогФайл();
Исключение
КонецПопытки;
КонецЕсли;
КонецПроцедуры
Процедура ПриОткрытии()
ПолноеИмяФайла = "C:Наше нужное местоAddInNative.dll";
Файл = Новый Файл(ПолноеИмяФайла);
Если Не Файл.Существует() Тогда
Сообщить("Не обнаружен файл внешней компоненты " + ПолноеИмяФайла + ОписаниеОшибки(), СтатусСообщения.Внимание);
Отказ = Истина;
Возврат;
КонецЕсли;
Попытка
ПодключитьВнешнююКомпоненту(ПолноеИмяФайла, "AddInNative", ТипВнешнейКомпоненты.Native);
Таймер = Новый("AddIn.AddInNative.AddInNativeExtension");
Таймер.StartTimer();
Исключение
Сообщить("Компонента " + ПолноеИмяФайла + " не загружена! " + ОписаниеОшибки(), СтатусСообщения.Внимание);
Возврат;
КонецПопытки;
ВремяСтарта = 0;
РазмерЛогФайла = 0;
НомерТекущейСтроки = 0;
КонецПроцедуры
Процедура ПриЗакрытии()
Если Таймер <> Неопределено Тогда
Таймер.StopTimer();
Таймер.Включен = Ложь;
Таймер = Неопределено;
КонецЕсли;
КонецПроцедуры
Процедура ПрочитатьЛогФайл()
ПутьКЛогФайлу = "C:ProgramData3CXDataLogs3CXDialer.log";
//ПутьКЛогФайлу = "C:Documents and SettingsAll UsersApplication Data3CXDataLogs3CXDialer.log"; // в XP
фсо = Новый ComОбъект("Scripting.FileSystemObject");
Файл = фсо.GetFile(ПутьКЛогФайлу);
текРазмерЛогФайла = Файл.Size();
Если РазмерЛогФайла = текРазмерЛогФайла Тогда
фсо = Неопределено;
Возврат;
КонецЕсли;
РазмерЛогФайла = текРазмерЛогФайла;
ЛогФайл = фсо.OpenTextFile(ПутьКЛогФайлу, 1);
Если НомерТекущейСтроки > 0 Тогда
Для i = 1 По НомерТекущейСтроки Цикл
ЛогФайл.SkipLine();
КонецЦикла;
КонецЕсли;
Пока Не ЛогФайл.AtEndOfStream Цикл
НомерТекущейСтроки = НомерТекущейСтроки + 1;
текСтрока = ЛогФайл.Readline();
Если Найти(текСтрока, "[Ringing]") = 0 Тогда Продолжить КонецЕсли;
датаДействия = Дата("20" + СтрЗаменить(СтрЗаменить(СтрЗаменить(Лев(текСтрока, 17), ".", ""), " ", ""), ":", ""));
Если датаДействия + 3 < ТекущаяДата() Тогда Продолжить КонецЕсли;
Если Найти(текСтрока, " Ins: ") > 0 Тогда
Действие = "Звонок"
Иначе
Действие = "Отбой"
КонецЕсли;
меткаВходВнутНомера = Найти(текСтрока, " DN=");
меткаИсходВнутрНомера = Найти(текСтрока, " IP=");
меткаНомераКонтрагента = Найти(текСтрока, " EP=");
ВходВнутрНомер = Сред(текСтрока, меткаВходВнутНомера + 4, меткаИсходВнутрНомера - 4 - меткаВходВнутНомера);
ИсходВнутрНомер = Сред(текСтрока, меткаИсходВнутрНомера + 4, меткаНомераКонтрагента - 4 - меткаИсходВнутрНомера);
текНомерКонтрагента = Прав(текСтрока, СтрДлина(текСтрока) - меткаНомераКонтрагента - 3);
Сообщить("датаДействия = " + датаДействия + ", Действие = " + Действие + ", ВходВнутрНомер = " + ВходВнутрНомер + ", ИсходВнутрНомер = " + ИсходВнутрНомер + ", НомерКонтрагента = " + текНомерКонтрагента);
КонецЦикла;
ЛогФайл.Close();
фсо = Неопределено;
КонецПроцедуры
Процедура Позвонить(НабираемыйНомер)
ЗапуститьПриложение("""C:Program Files (x86)3CXPhone3CXPhone.exe""" + " sip:" + НабираемыйНомер); // в 64
//ЗапуститьПриложение("""C:Program Files3CXPhone3CXPhone.exe""" + " sip:" + НабираемыйНомер);
КонецПроцедуры
3CXPhone.exe — это софтфон той же компании, устанавливается отдельно.
Встроенная функция ЧтениеТекста не смогла открыть лог-файл, поскольку он постоянно открыт самой АТС, пришлось прибегнуть к помощи FSO.
В Windows7 первый запуск формы выполняем по следующему сценарию: «Параметры управления учетными записями пользователей» — ползунок вниз «Никогда не уведомлять», затем перезагрузка, теперь запускаем форму и можно ползунок возвращать на место.
Теперь имея входящий, исходящий внутренние номера, номер контрагента и события «Звонок» и «Отбой» в 1С, мы ограничены только фантазией.
Всем удачи и всяческих благ!
Ваш Лёлёсь
Раскрась код, добавь скриншоты и будет тебе плюс
Читать лог-файл по таймеру — не самый лучший вариант. Можно воспользоваться внешней компонентой (есть на Инфостарте), которая мониторит изменение файла и вызывает внешнее событие. А если уже все-таки использовать таймер, то сначала логичней будет проверить изменение файла по атрибутам (время, размер), и только потом читать.
Поставил + за хорошее оформление публикации. Работа проделана не зря.
Спасибо за советы.
(1), (2) Да, да всё правильно, тут же исправил, но пока без той компоненты.
Что-то не смог её найти, адрес или название не подскажите?
(3) Конечно, это не совсем серьезная работа, а простая попытка быстро получить доступ к 3CX.
И Ваш плюс мне особенно дорог. Это первые 10 центов Скруджа Макдака:)
(4)http://infostart.ru/public/19235/
(5) О! Это для меня открытие!
По сравнению с таймером это очень элегантный способ.
Беру на вооружение.
Mucho gracias, Вам и автору!
Спасибо! Только у нас почему то в окне служебных сообщений ничего не пишется..
(7) Одна из причин — не подключена внешняя компонента, для проверки в процедуре ВнешнееСобытие вместо ПрочитатьЛогФайл() напишите Сообщить(Данные), при открытии обработки должны ритмично появляться сообщения.
Вторая возможная — убедитесь что файл 3CXDialer.log действительно находится по указанному Вами адресу.
Откройте его, в нём должны быть записи о совершённых вызовах.
Это для начала. Спасибо
(0) Лучше все таки не
а
Скажите, а Вы не пробовали через параметры коммандной строки 3CXPhone завершить разговор?
Получается, для начала разговора достаточно в коммандной строке дописать » dial:НомерТелефона», а можно ли завершить текущий разговор, аналогично?
Очень полезная публикация для меня!
Пришлась и ко времени и к месту.
Благодарен автору за доброту. (Голос по умолчанию прилагается))