powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Обмен данными типа String между VBA и C++ DLL
25 сообщений из 26, страница 1 из 2
Обмен данными типа String между VBA и C++ DLL
    #35943233
dgulet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте, уважаемые форумчане!
Кажется здесь еще не обсуждалась эта тема - как организовать обмен строковыми данными между офисными VBA-приложениями и простыми (не COM) DLL, написанными на С++. Туда и обратно.

Работаю над лингвистическим проектом. Написав программу на VBA под MS Word, которая работает с массивами данных типа String, пришел к выводу, что при увеличении объема данных программа начнет "тормозить". Для ускорения работы некоторых функций решил переписать их на С++ и загнать в DLL. Начал с простых попыток обмена данными, но столкнулся с тем, что строки (слова) в формате BSTR VBA неправильно передаются в DLL. Я не специалист в с++. Начал им заниматься недавно в Vsual Studio 2005. Ниже приведен код функций, которые удачно экспортируются в dll, но дают некорректный результат. Непонятно, в каком виде доходит string до dll? Нужна ваша помощь непрофессионалу.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
//---------------------------------DLL    
//работает неправильно (видимо ищет подстроку...)
// пробовал и другие операторы сравнения, безрезультатно...


#include "stdafx.h"
#include <string>
#include <iostream>


using namespace std;

string *WeekdayRu;

bool WINAPI DaNet( char *ss)
{
bool nalichie = false;
for(int k= 0 ; k< 7 ; k++)
{
    if (ss == WeekdayRu[k]) {nalichie = true; break;}
}

//MessageBox (0, ss, "Заголовок", MB_OK);   // хорошо бы здесь выводить значение ss, но не получается - компилятор выдает ошибки

return nalichie;
}

// функция загружает данные в память (массив указателей WeekdayRu)
int WINAPI Zagruzka()
{
 WeekdayRu = new string[ 7 ];
 
string SlovaRu[] = {"Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота", "Воскресенье"};
for(int i= 0 ; i< 7 ; i++)
{
WeekdayRu[i] = SlovaRu[i];
}
return  0 ;
}


Для VBA:
Public Declare Function Zagruzka Lib "C:\Mojadll.dll" () As Long
Public Declare Function DaNet Lib "C:\Mojadll.dll" (ByVal ss As String) As Boolean
---------------------------------------------------------------------------------------
Sub mydll()

Zagruzka
Dim Slovo As String
Slovo = "пятница" 'если я набираю "ятница" или "ница" - все равно возвращает "True" (почему ???)
MsgBox DaNet(Slovo)

End Sub
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #35943488
~PJ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dgulet,

в VB

Private Declare Sub ExtracAll Lib "extotms_.dll" (ByVal filename As String)

в С++ h модуле обяви например :

extern "C" void __declspec(dllexport) __stdcall ExtracAll(char * fileName);
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #35943667
pszMyNick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуйте так.
Код: plaintext
MessageBox ( 0 , ss.c_str(), "Заголовок", MB_OK);
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #35945177
dgulet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
~PJ,

Пишу строку
extern "C" void __declspec(dllexport) __stdcall ExtracAll(char * fileName);
в stdafx.h - компилятор выдает 4 ошибки.


pszMyNick,

Попробовал
MessageBox (0, ss.c_str(), "Заголовок", MB_OK);
компилятор выдает 1 ошибку - must have class/struct/union
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #35945610
~PJ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dgulet,

прошу прощения это я дал для компиляторов C++ Builder . Возможно там небольшое отличие.
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #35945832
dgulet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Главное, мне бы понять, почему в следующем фрагменте
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
bool WINAPI DaNet( char *ss)
{
bool nalichie = false;
for(int k= 0 ; k< 7 ; k++)
{
    if (ss == WeekdayRu[k]) {nalichie = true; break;}
}

//MessageBox (0, ss, "Заголовок", MB_OK);   // хорошо бы здесь выводить значение ss, но не получается - компилятор выдает ошибки

return nalichie;
}


происходят ошибки при сравнении?:
if (ss == WeekdayRu[k])
Т.е. при явном несовпадении строковых значений функция возвращает True.
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #35946239
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
потому что бессмысленно сравнивать указатель на char с экземпляром класса std::string. Для сравнения строк стоит использовать функцию strcmp() или её аналоги. Или, как вариант, из входного параметра тоже сконструировать объект типа std::string, и тогда уже сравнивать.
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #35947677
dgulet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
egorych,
благодарю за указание. Вы правы. Я и прежде пытался сравнивать строки используя оператор strcmp().
Только не получалось. Видимо я невнимательно отнесся к параметрам функции (см. MSDN):
int strcmp( const char *string1 const char *string2);
Нада было, наоборот, преобразовать std::string * в const char *. Вот так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
bool WINAPI DaNet(const char *ss)
{
bool nalichie = false;
for(int k= 0 ; k< 7 ; k++)
{
    if (strcmp (ss, WeekdayRu[k].c_str()) ==  0 ) {nalichie = true; break;}
}
return nalichie;
}
Теперь работает корректно.
Всем СПАСИБО.
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #35947779
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну можно и так написать:
Код: plaintext
1.
2.
3.
4.
5.
6.
bool WINAPI isWeekday( const std::string &searchDay )
{
   for( int i =  0 ; i <  7 ; ++i ) 
      if ( searchDay == WeekdayRu[ i ] ) return true; 
   
   return false;
}
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #35954040
dgulet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А как определить количество букв в элементе массива WeekdayRu[k],
или длину элемента?
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Обмен данными типа String между VBA и C++ DLL
    #38293291
hey ho
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Джентельмены, а вот такой вопрос - хочу также распознать текст из VBA, передаю его в С++ как ByVal String, принимаю как char. Далее использую switch:

case 'B':
return 111;
break;

case 'BA':
return 222;
break;

Если текст начинается с B, то всегда получается 111 :(
Как этого избежать, используя switch?

PS как видите, я ламер :)
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #38293347
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hey ho, case 'BA' должен, как минимум, варнинг при компиляции порождать, вероятно, не зря
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #38293477
Кот Чеширский
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dgulet Написав программу на VBA под MS Word, которая работает с массивами данных типа String, пришел к выводу,

А почему VBA не под Excel?
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #38296945
hey ho
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
egorychhey ho, case 'BA' должен, как минимум, варнинг при компиляции порождать, вероятно, не зря
Намекаете на то, что switch работает с однобуквенными вариантами?
Я погуглил и не нашёл, ранее сталкивался с тем, что однобуквенные работали, многобуквенные нет. Что где не так делаю?
Попробовал то же самое через if else, там тоже не выходит (руки мои оттуда растут, да!).
В идеале мне нужно запилить функцию типа x(ABC100500XYZ;N), распарсить её на ABC, 100500 и XYZ и в зависимости от значений этих компонентов, вернуть обратно в VBA результаты типа 100500/N или 100500^N.
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #38296978
hey ho
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Погуглил ещё, понял что мою проблему через char не решить. Теперь делаю так:
VBA
Declare PtrSafe Function analysis Lib "blahblah.dll" (ByVal word As String, ByRef N as Double) As Double

C++
#include <iostream>
#include <string>
double __stdcall analysis(std::string & code, double & N)
{
if (word == "ABC") return 111;
else
if (code == "BAC") return 222;
else
return 666;
}

на этой петрушке всё компилится, но при пересчёте экселя он падает.
Кто найдёт шайтана?
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #38296997
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hey hoКто найдёт шайтана?
сам ищи :)

ByVal word As String в С приедет как LPCSTR
строки сравнивать функцией strcmp

пример- http://support.microsoft.com/kb/187912/ru
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #38297022
hey ho
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропил, теперь вот как:
C++
#include <iostream>
#include <string>
#include <windows.h>
double __stdcall analysis(LPCSTR code, double & N)

{
if (!strcmp(word, "ABC")) return 111;
else
if (!strcmp(word, "BAC")) return 222;
else
return 666;
}

Компилится, эксель не падает, но выдаёт 666 в любом случае.
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #38297041
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hey ho,

в отладчике смотри что происходит
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #38297066
hey ho
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропилhey ho,

в отладчике смотри что происходит
Я dll в связке с Excel не знаю как отлаживать :(
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #38297082
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hey hoВ идеале мне нужно запилить функцию типа x(ABC100500XYZ;N), распарсить её на ABC, 100500 и XYZ и в зависимости от значений этих компонентов, вернуть обратно в VBA результаты типа 100500/N или 100500^N.в идеале надо в VBA распарсить, и не мучать себе и окружающим мозги ;-))
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #38297097
hey ho
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
egorychв идеале надо в VBA распарсить, и не мучать себе и окружающим мозги ;-))
В VBA уже сделано. Сверху парсинга ещё калькуляций прилично, поэтому скорость уже играет роль.
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #38297115
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hey hoИзопропилhey ho,

в отладчике смотри что происходит
Я dll в связке с Excel не знаю как отлаживать :(
добавить в солюшн эксель (excel.exe), задать параметры, установить контрольные точки и запустить безобразие
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #38297151
hey ho
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Изопропилдобавить в солюшн эксель (excel.exe), задать параметры, установить контрольные точки и запустить безобразие
Спасибо, буду пробовать.
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #38300727
hey ho
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Что-то не выходит :(
Разбираюсь с типами данных, пишут, что LPCSTR и "текст в двойных кавычках" (лулз,ну не знаю я как оно правильно называется) нельзя сравнивать. Как правильно конвертнуть?

PS подумав о том как жить дальше, твёрдо решил записаться на курсы С++ :)
Кстати, кто чего может в Москве посоветовать? Или может кто уроки даёт?
...
Рейтинг: 0 / 0
Обмен данными типа String между VBA и C++ DLL
    #38300811
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hey ho,
>> Разбираюсь с типами данных, пишут, что LPCSTR и "текст в двойных кавычках" (лулз,ну не знаю я как оно правильно называется) нельзя сравнивать. Как правильно конвертнуть?
strcmp() спасёт отца русской демократии

>> PS подумав о том как жить дальше, твёрдо решил записаться на курсы С++ :) Кстати, кто чего может в Москве посоветовать?
дом книги на новом арбате посети
...
Рейтинг: 0 / 0
25 сообщений из 26, страница 1 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / Обмен данными типа String между VBA и C++ DLL
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]