Можно сделать так.
X++:
class ExcelFuncs
{
}
static client ComVariant GetValue(Com Range)
{
ComDispFunction func = new ComDispFunction(range, "Value", ComDispContext::PropertyGet);
ComVariant var = new ComVariant(ComVariantInOut::Out_retVal, ComVariantType::VT_ERROR);
int line;
int i;
str s;
;
SetPrefix("CallWasRejectedByCallee");
while (true)
try
{
line = infolog.line();
func.call(var);
return var;
}
catch
{
if (infolog.line() > line)
{
s = infolog.text(line+1);
if (strscan(s, "Value", 1, strlen(s)))
{
s = substr(s, strscan(s, "0x", 1, strlen(s))+2, 8);
if (s == "80010001")
{
sleep(100);
infolog.cut(line+1);
continue;
}
}
}
throw Exception::Error;
}
throw error("Ошибка при получении значения!");
}
Пример вызова.
X++:
static void Sample(Args _args)
{
ComExcelDocument_Ru excel = new ComExcelDocument_Ru();
Com doc;
Com app;
Com Sheet;
Com Range;
ComVariant var;
;
excel.open("c:\\Temp\\TestExcel.xls", true);
doc = excel.getComDocument();
app = doc.Application();
sheet = app.ActiveSheet();
range = sheet.range("A1:J1");
info("aaa");
while (true)
{
// info("bbb");
var = ExcelFuncs::GetValue(range);
}
}
Для проверки можно запустить джоб и внести что-либо в ячейку. Пока будет происходить пользовательский ввод - код ожидает его кончания (аналогично с диалоговыми окнами). По окнчанию ввода (закрытию диалогового окна) обработка продолжится.
Если закрыть окно Excel, то произойдет окончание работы job'а по exception'у.
Хотя, мне это решение не нравится.
Во-первых, нет возможности явно определить код возврата из вызова функции (при получении значения, не равного S_OK, ядро генерирует exception). Например, если раскомментарить строку info("bbb"), то в инфолог будет выводиться форматная строка без передачи параметров (вместо имени функции и кода ошибки будут %1, %2 и т.д.) (проверял на SP3 и SP5 без роллапов)
Во-вторых, ожидание пока пользователь как-то отреагирует на появившиеся диалоги (возможность ввода данных в ячейки оставлена для примера). Напомню, что пока будут выведены эти окна, интерфейсы не будут работать (будет возвращаться ошибка 0x80010001, либо не будут находиться какие-то методы).
Еще есть такой вариант - написать Comобъект-обертку над методами Excel'я с возможностью получения кода возврата из экселевских методов. Тогда пропадет неоднозначность, правда, второй пункт и в этом случае останется в силе.