Как сделать конфигурацию «1С:Предприятие 8» приложением QuickBooks. Проходим авторизацию OAuth 1.0a+OpenID 2.0

Публикация № 671523

Программирование - Практика программирования

52
Пришло время, когда интеграция со сторонними организациями и их приложениями стала необходимостью для успешного ведения бизнеса. В этой статье будет рассмотрено прохождение авторизации OAuth 1.0a+OpenID 2.0 и превращение конфигурации «1С:Предприятие 8» в приложение QuickBooks.

Вводные данные:

Прежде чем переходить к основной теме статьи, необходимо сделать лирическое отступление и описать некоторые неизвестные слова для неискушенного разработчика.

OAuth 1.0a — это открытый протокол авторизации, который позволяет предоставить третьей стороне ограниченный доступ к защищённым ресурсам пользователя без необходимости передавать ей (третьей стороне) логин и пароль. С детальным описанием протокола можно ознакомится в информационном документе RFC 5849.

OpenID 2.0 — открытый стандарт децентрализованной системы аутентификации, предоставляющей пользователю возможность создать единую учётную запись для аутентификации на множестве не связанных друг с другом интернет-ресурсов, используя услуги третьих лиц.

QuickBooks — представляет собой пакет программного обеспечения для бухгалтерского учета. Продукты QuickBooks ориентированы главным образом на малые и средние предприятия и предлагают приложения для бухгалтерского учета на местах, а также версии на основе облачных вычислений.

Проблематика:

Многие компании за границей используют QuickBooks для бухгалтерского учета и все конфигурации «1С:Предприятие 8», которые фирма 1С предоставляет через известный сайт для западного рынка, пока не могут закрыть вопросы бухгалтерского учета. В то же время конфигурации подходят для складского учета и для других целей. На этом стыке возникает потребность в интеграции систем. Большинство программистов привыкли, что интеграция — это обмен сообщениями определенного формата, но когда они встречают столь сложную авторизацию и аутентификацию невольно опускаются руки.

QuickBooks использует комбинацию OAuth 1.0a + OpenID 2.0 для интеграции через приложение (App). Приложение можно создать по ссылке. После создания приложения станут доступны ключи доступа. Вот об комбинировании этой солянки и пойдет речь ниже.

ШАГ 1. Создаем приложение:

После создания приложения, необходимо получить ключи разработчика для песочницы. В нашем случае они будут:
oauth_consumer_key = qyprdEQRuexcfM4P05zd2vB0baw2TB 
oauth_consumer_secret = AbQpDjBAQlTHt08GBT9yktfuklrZJkvBL7Hswhoc
Ключи разработчика для песочницы QuickBooks

ШАГ 2. Получаем request token

Приложение должно запросить набор временных учетных данных token, также известный как request token. Он еще не связаны с какой-либо компанией QuickBooks конкретного пользователя. Приложением будет выступать конфигурация «1С:Предприятие 8» и для прохождения данного этапа необходимо реализовать некоторую базовую функциональность:

// Returns unique token your application should generate for each unique request.
//
// Returns:
//  String.
//
Function OAuthNonce()
    Return String(New UUID);  
EndFunction // OAuthNonce()

// Returns default oauth signature method name.
//
// Returns:
//  String.
//
Function OAuthSignatureMethod()
    Return "HMAC-SHA1";
EndFunction // OAuthSignatureMethod()

// Returns a sequence of characters or encoded information identifying when a certain 
// event occurred, usually giving date and time of day, sometimes accurate to a small 
// fraction of a second.
//
// Returns:
//  String.
//
Function OAuthTimestamp()
    Return Format(CurrentSessionDate() - Date("19700101"), "NG=0");
EndFunction // OAuthTimestamp()

// Returns the OAuth version 1.0.
//
// Returns:
//  String.
//
Function OAuthVersion()
    Return "1.0";
EndFunction // OAuthVersion()

Так же реализуем в виде функций ссылки (URL) для прохождения авторизации:

// Only for internal use.
//
Function AuthorizeUrl() Export 
    Return "https://appcenter.intuit.com/Connect/Begin";   
EndFunction // AuthorizeUrl()

// Only for internal use.
//
Function CallbackUrl() Export
    Return "https://httpbin.org/forms/post?";  
EndFunction // CallbackUrl()

// Only for internal use.
//
Function TokenServerName()
    Return "https://oauth.intuit.com";   
EndFunction // TokenServerName()

// Only for internal use.
//
Function RequestTokenResource()
    Return "/oauth/v1/get_request_token";   
EndFunction // RequestTokenResource()

// Only for internal use.
//
Function AccessTokenResource()
    Return "/oauth/v1/get_access_token";   
EndFunction // AccessTokenResource()

// Only for internal use.
//
Function AppServerName() 
    Return "https://appcenter.intuit.com";
EndFunction // AppServerName()

// Only for internal use.
//
Function AppDisconnectResource()
    Return "/api/v1/connection/disconnect";
EndFunction // AppDisconnectResource()

Следующий код реализует получение `request token`:

// Only for internal use.
//
Procedure RequestToken() Export
        
    OAuthList = New ValueList();
    OAuthList.Add(OAuthNonce(),           "oauth_nonce");
    OAuthList.Add(OAuthVersion(),         "oauth_version");
    OAuthList.Add(CallbackUrl(),          "oauth_callback");
    OAuthList.Add(OAuthTimestamp(),       "oauth_timestamp");
    OAuthList.Add(OAuthConsumerKey(),     "oauth_consumer_key");
    OAuthList.Add(OAuthSignatureMethod(), "oauth_signature_method");
        
    Parameters = NewHTTPSecureParameters();
    Parameters.HTTPMethod = "GET";
    Parameters.ServerName = TokenServerName();
    Parameters.Resource   = RequestTokenResource();
    Parameters.Headers.Insert("Authorization", 
        AuthorizationHeader(Parameters.HTTPMethod, 
            Parameters.ServerName, 
            Parameters.Resource, 
            OAuthList));
    Parameters.Fields.Add("oauth_token");
    Parameters.Fields.Add("oauth_token_secret");
        
    HTTPSecureRequest(Parameters, EncryptedData);
    
EndProcedure // RequestToken()

Функция NewHTTPSecureParameters описывает структуру параметров запроса.
Методы шифрования в данной статье не рассматриваются и потому, EncryptFields не будет использован.

// Only for internal use.
//
Function NewHTTPSecureParameters() Export
    
    Parameters = New Structure;
    Parameters.Insert("HTTPMethod");
    Parameters.Insert("ServerName");
    Parameters.Insert("Resource");
    Parameters.Insert("Headers", New Map);
    Parameters.Insert("Fields", New Array);
    Parameters.Insert("EncryptFields", New Array);    
    Return Parameters;
    
EndFunction // NewHTTPSecureParameters()

Функция AuthorizationHeader формирует заголовок авторизации.

// Only for internal use.
//
Function AuthorizationHeader(HTTPMEthod, ServerName, Resource, OAuthList)
    
    RequestUrl = StrTemplate("%1%2", ServerName, Resource);
    
    Signature = "";
    URLEncoding = StringEncodingMethod.URLEncoding;
    
    URIStructure = URIStructure(RequestUrl);
    For Each Parameter In URIStructure.Parameters Do
        OAuthList.Add(Parameter.Value, Parameter.Key);   
    EndDo;
    
    OAuthList.SortByPresentation();
    For Each OAuthItem In OAuthList Do
        
        If IsBlankString(Signature) Then
            Signature = Signature + OAuthItem.Presentation + "=" 
                + EncodeString(OAuthItem.Value, URLEncoding);    
        Else
            Signature = Signature + "&" + OAuthItem.Presentation + "=" 
                + EncodeString(OAuthItem.Value, URLEncoding);   
        EndIf;
        
    EndDo;
    
    Position = StrFind(RequestUrl, "?");
    If Position > 0 Then
        RequestUrl = Left(RequestUrl, Position - 1);    
    EndIf;
    
    OAuthList.Add(OAuthSignature(HTTPMEthod, RequestUrl, 
        OAuthSignatureMethod(), Signature, EncryptedData), "oauth_signature");

            
    Authorization = "OAuth ";
    For Each OAuthItem In OAuthList Do
        
        If StrFind(OAuthItem.Presentation, "oauth_") = 1 Then
            
            If Authorization = "OAuth " Then
                Authorization = Authorization + OAuthItem.Presentation + "=""" 
                    + EncodeString(OAuthItem.Value, URLEncoding) + """";
            Else 
                Authorization = Authorization + "," + OAuthItem.Presentation + "=""" 
                    + EncodeString(OAuthItem.Value, URLEncoding) + """";
            EndIf;
                
        EndIf;
        
    EndDo;
             
    Return Authorization;    
    
EndFunction // AuthorizationHeader()

Функция URIStructure предназначена для разбора ссылки на составляющие.

// Dissembles URI string and returns it as a structure.
// Based on RFC 3986.
//
// Parameters:
//  StringURI - String - reference to the resource in the format:
//      <schema>://<login>:<password>@<host>:<port>/<path>?<parameters>#<anchor>
//
// Returns:
//  Structure - with keys:
//      * Schema       - String - schema.
//      * Login        - String - user login.
//      * Password     - String - user password.
//      * ServerName   - String - part : from the StringURI.
//      * Host         - String - host name.
//      * Port         - Number - port number.
//      * PathOnServer - String - part ?# from the StringURI.
//      * Parameters   - Map    - parsed parameters from the StringURI. 
//
Function URIStructure(Val StringURI) Export

    StringURI = TrimAll(StringURI);
    Parameters = New Map;
    
    // Schema
    Schema = "";
    Position = StrFind(StringURI, "://");
    If Position > 0 Then
        Schema = Lower(Left(StringURI, Position - 1));
        StringURI = Mid(StringURI, Position + 3);
    EndIf;

    // Connection string and path on the server.
    ConnectionString = StringURI;
    PathOnServer = "";
    Position = StrFind(ConnectionString, "/");
    If Position > 0 Then
        PathOnServer = Mid(ConnectionString, Position + 1);
        ConnectionString = Left(ConnectionString, Position - 1);
    EndIf;
    
    // Parameters
    Position = StrFind(PathOnServer, "?");
    If Position > 0 Then
        ParametersString = Mid(PathOnServer, Position + 1);        
        ParametersArray = StrSplit(ParametersString, "&");
        For Each Parameter In ParametersArray Do
            Position = StrFind(Parameter, "=");
            If Position > 1 Then
                Parameters.Insert(Left(Parameter, Position - 1), Mid(Parameter, Position + 1));    
            EndIf;    
        EndDo;
    EndIf;
        
    // User information and server name.
    AuthorizeString = "";
    ServerName = ConnectionString;
    Position = StrFind(ConnectionString, "@");
    If Position > 0 Then
        AuthorizeString = Left(ConnectionString, Position - 1);
        ServerName = Mid(ConnectionString, Position + 1);
    EndIf;

    // Login and password.
    Login = AuthorizeString;
    Password = "";
    Position = StrFind(AuthorizeString, ":");
    If Position > 0 Then
        Login = Left(AuthorizeString, Position - 1);
        Password = Mid(AuthorizeString, Position + 1);
    EndIf;

    // Host and port.
    Host = ServerName;
    Port = "";
    Position = StrFind(ServerName, ":");
    If Position > 0 Then
        
        Host = Left(ServerName, Position - 1);
        Port = Mid(ServerName, Position + 1); 
        For Index = 1 To StrLen(Port) Do
            Symbol = Mid(Port, Index, 1);
            If Not IsNumber(Symbol) Then
                Port = "";
                Break;    
            EndIf;
            
        EndDo;
        
        If IsBlankString(Port) Then
            If Schema = "http" Then
                Port = "80";
            ElsIf Schema = "https" Then
                Port = "443";
            EndIf;
        EndIf;
 
    EndIf;

    Result = New Structure;
    Result.Insert("Schema", Schema);
    Result.Insert("Login", Login);
    Result.Insert("Password", Password);
    Result.Insert("ServerName", ServerName);
    Result.Insert("Host", Host);
    Result.Insert("Port", ?(IsBlankString(Port), Undefined, Number(Port)));
    Result.Insert("PathOnServer", PathOnServer);
    Result.Insert("Parameters", Parameters);

    Return Result;

EndFunction // URIStructure()

Функция OAuthSignature формирует подпись из переданных данных.
Внимание на реализации функции HMAC_SHA1(UrlSignature, KeySignature) заострять не буду оно довольно тривиальное и достаточно легко реализуется.
Методы шифрования в данной статье не рассматриваются и потому ветка IsBlankString(EncryptNumber) не имеет реализации чтения зашифрованных значений.

Function OAuthSignature(Val HTTPMethod, Val URL, Val OAuthSignatureMethod, 
    Val PreparedSignature, EncryptedData) Export
    
    UrlSignature = HTTPMethod + "&" 
        + EncodeString(URL, StringEncodingMethod.URLEncoding) + "&" 
        + EncodeString(PreparedSignature, StringEncodingMethod.URLEncoding);
   
    KeySignature = EncryptedFiledValue("oauth_consumer_secret", EncryptedData) 
        + "&" + EncryptedFiledValue("oauth_token_secret", EncryptedData);
    
    If Upper(TrimAll(OAuthSignatureMethod)) = "HMAC-SHA1" Then
 
        Signature = HMAC_SHA1(UrlSignature, KeySignature);
        
    Else
        
        ErrorMessage = NStr("en = 'Signature method is not supported.';
            |ru = 'Сигнатурный метод не поддерживаеться.'");
            
        Raise ErrorMessage;
        
    EndIf;
    
    Return Signature;           
    
EndFunction // OAuthSignature()

// Only for internal use.
//
Function EncryptedFiledValue(FieldName, EncryptedData)
    
    SearchResult = EncryptedData.Find(FieldName, "FieldName");
    If SearchResult <> Undefined Then
        
        FieldValue = SearchResult.FieldValue;
        EncryptNumber = SearchResult.EncryptNumber;
        If IsBlankString(EncryptNumber) Then
            Return FieldValue;
        Else
            Return "";
        EndIf;
        
    Else
        
        Return "";    
        
    EndIf;
  
EndFunction // EncryptedFiledValue()

Процедура HTTPSecureRequest, непосредственно, выполняет обращение к серверу авторизации и при успешном результате полученные данные добавляет в таблицу EncryptedData, таблица имеет вид:
Реквизиты таблицы с зашифрованными данными OAuth 1.0a

Procedure HTTPSecureRequest(Parameters, EncryptedData) Export
    
    URIStructure = IHL_CommonUseClientServer.URIStructure(
        Parameters.ServerName + Parameters.Resource);
    
    HTTPRequest = New HTTPRequest(URIStructure.PathOnServer);
    For Each Header In Parameters.Headers Do 
        HTTPRequest.Headers.Insert(Header.Key, Header.Value);
    EndDo;
    
    HTTPConnection = New HTTPConnection(
        URIStructure.Host,
        URIStructure.Port,
        URIStructure.Login,
        URIStructure.Password,
        ,
        ,
        New OpenSSLSecureConnection(Undefined, Undefined));
        
    HTTPResponse = HTTPConnection.CallHTTPMethod(Parameters.HTTPMethod, 
        HTTPRequest);
    
    If HTTPResponse.StatusCode = 200 Then
        
        ContentType = HTTPResponse.Headers.Get("Content-Type");
        If ContentType = "text/plain" Then
            
            Body = HTTPResponse.GetBodyAsString();
            BodyParts = StrSplit(Body, "&");
            For Each BodyPart In BodyParts Do
                
                Position = StrFind(BodyPart, "=");
                If Position > 0 Then
                    FieldName  = Left(BodyPart, Position - 1);
                    FieldValue = Mid(BodyPart, Position + 1);
                    If Parameters.Fields.Find(FieldName) <> Undefined Then
                        RowResult = EncryptedData.Find(FieldName, "FieldName");
                        If RowResult = Undefined Then
                            RowResult = EncryptedData.Add();
                        EndIf;
                        RowResult.FieldName  = FieldName;
                        RowResult.FieldValue = FieldValue;
                    EndIf;
                EndIf;
            EndDo;
        EndIf;
    Else
        Raise HTTPResponse.GetBodyAsString();
    EndIf;
    
EndProcedure // HTTPSecureRequest()

ШАГ 3. Авторизация пользователя и приложения на QuickBooks

На этом шаге конфигурация «1С:Предприятие 8» должна перенаправить пользователя на ресурс для авторизации на адрес https://appcenter.intuit.com/Connect/Begin?oauth_token=token, где oauth_token равен полученному на предыдущем этапе. После успешной авторизации пользователя и предоставления доступа приложения к компании в QuickBooks, будет выполнено переход на CallbackUrl (вы можете разместить сервер который будет обрабатывать запросы или воспользоваться перехватом управления как выполнено в видео, что ниже).

ШАГ 4. Замена временного токена на постоянный

На последнем шаге необходимо заменить временный oauth_token на постоянный:

  • Функция OAuthToken() возвращает временный token полученный на шаге 2;
  • Функция OAuthVerifier() возвращает значение oauth_verifier, которое было получено на шаге 3 при переадресации на CallbackUrl:
// Only for internal use.
//
Procedure AccessToken() Export
    
    OAuthList = New ValueList();
    OAuthList.Add(OAuthNonce(),             "oauth_nonce");
    OAuthList.Add(OAuthToken(),             "oauth_token");
    OAuthList.Add(OAuthVersion(),           "oauth_version");
    OAuthList.Add(OAuthVerifier(),          "oauth_verifier");
    OAuthList.Add(OAuthTimestamp(),         "oauth_timestamp");
    OAuthList.Add(OAuthConsumerKey(),       "oauth_consumer_key");
    OAuthList.Add(OAuthSignatureMethod(),   "oauth_signature_method");
    
    Parameters = NewHTTPSecureParameters();
    Parameters.HTTPMethod = "GET";
    Parameters.ServerName = TokenServerName();
    Parameters.Resource   = AccessTokenResource();
    Parameters.Headers.Insert("Authorization", 
        AuthorizationHeader(Parameters.HTTPMethod, 
            Parameters.ServerName,
            Parameters.Resource,
            OAuthList));
    Parameters.Fields.Add("oauth_token");
    Parameters.Fields.Add("oauth_token_secret");
        
    HTTPSecureRequest(Parameters, EncryptedData);
      
EndProcedure // AccessToken()

После успешного выполнения необходимо сохранить данные таблицы EncryptedData и в дальнейшем использовать их для формирования AuthorizationHeader для выполнения запросов к ресурсам компании QuickBooks.

Вместо послесловия, полноценную рабочую версию не выкладываю из-за ограниченной лицензии, но мне кажется, не составит большого труда дописать недостающие части. Успехов в начинаниях.

Статья в личном блоге клац

52

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. Tahallus 425 11.09.17 03:43 Сейчас в теме
Если не секрет можете рассказать для чего и как используется QuickBooks + 1С
2. pbazeliuk 1654 11.09.17 07:35 Сейчас в теме
(1) QuickBooks полноценная бухгалтерская система, в свою очередь конфигурация 1С используется как система для складского учета (1C:Small Business). Во многих организациях есть подобные связки бухгалтерия + складская или управленческая система.
3. flyer 217 11.09.17 12:39 Сейчас в теме
(2) у QuickBooks разве нет модуля управление складом?
4. pbazeliuk 1654 11.09.17 13:24 Сейчас в теме
(3) В "1С:Бухгалтерии" так же есть управление складом, но, как-то, не очень удобно, удобней "1С:Управление торговлей"... В "1С:Бухгалтерии" так же есть возможность учитывать розничные продажи, но, как-то, не очень удобно, удобней "1С:Розница"... и таких примеров масса.

В QuickBooks можно взять в оренду WMS как приложение, тут уже вопрос в цене.
5. kolya_tlt 11 12.09.17 14:20 Сейчас в теме
(4) если честно, так до конца и не понятно зачем делать какую-то конфигурацию.
у меня вот какой вопрос: удавалось ли решать вопросы единой аутентификации для всех систем, как в примере выше? QuickBooks + 1С.
затык заключается, в том, что openID 1C можно аутентифицироваться только в системах 1С, а хотелось бы иметь доступ во все платформы.
6. pbazeliuk 1654 12.09.17 14:37 Сейчас в теме
(5) если говорить об OpenID, то у стандарта всегда есть 3 стороны, в данном случае QuickBooks выступает как провайдер, клиент как клиент зарегистрированный у провайдера, 1С конфигурация как приложение, которое получает доступ к данным.
Для других систем так же можно пройти авторизацию, если провайдер поддерживается этими системами.

Аутентификацию к различным системам есть возможность выполнить с помощью https://infostart.ru/public/560516/ версии выше чем 0.9.0 (которая пока не доступна, но готовится к релизу, а пока делается описание, шаблоны для того чтобы выложить встраиваемую конфигурацию на общее обозрение).
7. kolya_tlt 11 12.09.17 14:54 Сейчас в теме
(6) у нас потребность не получении данных, в том, чтобы выполнив вход в провайдере (который не на 1С) попасть в систему 1С как в приложение.
8. pbazeliuk 1654 12.09.17 15:16 Сейчас в теме
(7) То что вы спрашиваете это не тема этой статьи, совсем. Но возможность такое сделать есть. Подали мне идею для платного модуля :)
9. kolya_tlt 11 12.09.17 16:35 Сейчас в теме
10. natalic 18.09.17 09:38 Сейчас в теме
Здравствуйте! в какой программе реализуется весь функционал? где писать код?
11. pbazeliuk 1654 18.09.17 10:30 Сейчас в теме
(10) Добрый день, все реализуется в «1С:Предприятие 8», после прохождения авторизации можно использовать все команды из API QuickBooks.
12. BigBoss 2 15.11.17 09:29 Сейчас в теме
(11) День добрый, вопрос: я как понимаю интеграция заключается в следующем: склад и всё что с ним связанно оформляется в 1С, а фин.операции оформляются в QuickBooks?
13. pbazeliuk 1654 15.11.17 10:16 Сейчас в теме
(12) Все зависит от того, какая конфигурация выбрана за основу и на сколько тесной необходима интеграция.
14. ylyas 25 15.12.18 23:03 Сейчас в теме
Ни где не нашел листинг процедуры из общего модуля: IHL_CommonUseClientServer.URIStructure
Можете привести?
16. ylyas 25 17.12.18 13:50 Сейчас в теме
(15) Благодарю, очень любезно с вашей стороны. Очень полезный экспириенс.
17. 0SpAGeTTi010 19.12.18 17:01 Сейчас в теме
Добрый Вечер! Опишите сам процесс подключения к песочнице.
Не совсем понятно, как ориентироваться на сайте, и какие поля там понадобятся в подключении. Спасибо
18. pbazeliuk 1654 21.12.18 21:31 Сейчас в теме
(17) About 18 months ago, we announced support for OAuth 2.0. At that time, all new apps started using OAuth 2.0 for authorization, and (optionally) OpenID Connect for single sign-on authentication.

We also launched an open OAuth 2.0 migration beta program so developers could give us feedback on our tools and resources. Over the past year, we have provided several OAuth 2.0 libraries, and included modules to migrate OAuth 1.0 tokens to OAuth 2.0 including, most recently, when we released libraries in Python and Node.js.

Если кратко, статья уже не актуальна. Уже OAuth 2.0, там все проще и проблем не должно возникать
19. ylyas 25 23.12.18 19:05 Сейчас в теме
(18)
Боюсь, что вы не до оцениваете ценность вашей статьи.
Мне, например, не к QuickBooks подключаться нужно.
И метод сигнатур другой используется.
Но есть еще куча ресурсов, которые по прежнему пользуют oauth1.0a( как в моем случае).
По этом ваша публикация очень хороший и наглядный пример для меня. :)
20. ylyas 25 23.12.18 19:17 Сейчас в теме
У меня вот к вам другой вопрос, Петр.
скажите, порядок выполнения запросов для авторизации(request token ->access token) всегда остается один и тот же независимо от oauth_signature_method ?
Просто в моем случае это private app и RSA-SHA1. То есть, на сайт выложен public key а у меня есть private key.
Или в таком случае уже не нужно запрашивать токен доступа? можно сразу выполнять запрос к данным передавая секретный ключ(oauth_token_secret) в заголовке?
23. pbazeliuk 1654 25.12.18 10:31 Сейчас в теме
(20) Пришлите ссылку на API, я вам порядок в личку распишу.
21. 0SpAGeTTi010 24.12.18 10:28 Сейчас в теме
Конечно, подключение к QuickBooks oline большая проблема для меня, и эта статься единственное от чего я отталкивался за все это время, правда все безрезультатно.
Теперь, у меня возник вопрос к подключению QuickBooks Desktop, вот тут на самом деле все проще должно быть, но нигде нет примеров подключения на встроенном языке 1С.
qbsdk130.exe я уже установил, хочу знать как запускать его программно из модуля 1с
22. ylyas 25 24.12.18 11:20 Сейчас в теме
(21) пробуйте ЗапуститьПриложение
24. 0SpAGeTTi010 04.01.19 14:00 Сейчас в теме
(22)Добрый день и С новым годом! Спасибо за предложенный вариант, но у меня нет необходимости открывать демонстративно qbsdk130.exe в 1С.
Мне нужно пользоваться инструменты qbsdk130.exe для интеграции. Как подключаться к qbsdk130.exe из модуля 1С, мне не известно, в интернете нет ни каких примеров(
25. ylyas 25 04.01.19 21:05 Сейчас в теме
(24)
Не понимаю о чем речь. вообще. пишите в личку. если интересно
26. 0SpAGeTTi010 05.01.19 14:59 Сейчас в теме
(25)Да, интересно. Напишите мне первым, у меня нет возможности до Вас дописаться
27. 0SpAGeTTi010 11.01.19 10:49 Сейчас в теме
Добрый день! Вы у меня в друзьях, а написать Вам не могу. Напишите мне первым, пожалуйста. У меня один вопросик будет
Оставьте свое сообщение