Привет. 

TS 3.x

Есть документ Excel(.xls) открытый вот так:

var Excel = new ActiveXObject('Excel.Application');
Excel.Workbooks.Open(filePath);

У кого есть опыт работы, подскажите как:

1. Добавить пустой рядок в качестве 1-го(подвинув остальные вниз).

2. Заполнить ячейки этого рядка(припустим первых 10), интересует именно доступ.

3. Настроить ширину колонок.



*VS Debugger виснет при попытке взглянуть в объект.

**Нормальной документации не нашел, если у кого-то завалялась - буду благодарен

Нравится

2 комментария

Проще всего в Excel запустить запись макроса, проделать всё вышеупомянутое, а потом изучать сгенерированный код на VBA и переводить его на синтаксис JS.

Потыкал и нашел.

 

try {
        var excel = new ActiveXObject('Excel.Application');
        var workBooks = excel.Workbooks.Open(TempFileName.Value);
        var excelSheet = workBooks.Worksheets(1);
        excelSheet.Activate();
        excelSheet.Range('A1:K1').Insert(-4121);
        excelSheet.Range('A1').Formula = 'Ячейка А1';
        excelSheet.Range('B1').Formula = 'Ячейка А2 ';
    //  ......
        excelSheet.Range('K1').Formula = 'Ячейка К1';
        excelSheet.Columns('A:K').AutoFit();
        workBooks.Save();
 
    }
    finally {
        excelSheet = System.EmptyValue;
        workBooks = System.EmptyValue;
        excel.Quit();
        excel = System.EmptyValue;
        CollectGarbage();
    }
    

1.Добавление пустого рядка было сделано через Insert со смещением вниз.

2. Заполнение через метод Formula об. Range

3. Использовал AutoFit так как изменять значения Width или ColumnWidth не давало(read-only).

*Ещё обратите внимание на блок finally при таких действиях процесс excel.exe который был создан убивается.

Показать все комментарии

Добрый день!
Появилась необходимость сделать кликабельную ссылку в карточке Продажи (Террасофт 3.4.0.48.).
Создала поле, в которое пользователь вводит ссылку. К этому полю прикрепила кнопку, по нажатию на которое выполняется действие amiOpenLink. Обра

function amiOpenLinkOnExecute(ActionMenuItem, Sender) {
var URLName = dlData.Dataset.Values('TenderTarget');
URLName = (URLName != null) ? URLName : '';

 var browser = new ActiveXObject("InternetExplorer.Application");
    browser.Navigate(URLName);
    browser.Visible = true;    
}

Этот вариант решения работает хорошо, но я бы хотела открывать не строго в InternetExplorer, а в браузере по умолчанию. В Мозиле или в хроме, например. Если ссылка прикрепляется как файл, то именно это и происходит. Однако, выцепить коды какими именно открывается браузер по умолчанию у меня не получилось. Нашла на форуме строку:

 var browser = new ActiveXObject("Shell.Explorer.2");

Но она не срабатывает и выдает ошибку.

Нравится

2 комментария

используйте

System.OpenFile(URL, 1);

система сама разберется, что это URL, а не FilePath и откроет браузер по-умолчанию

"Андросов Дмитрий" написал:
System.OpenFile(URL, 1);

Спасибо! Не срабатывал этот вариант оттого, что писала для проверки в поле yandex.ru, а ссылку нужно было писать http:\yandex.ru или www.yandex.ru.

Показать все комментарии

Здравствуйте!

Есть необходимость создать ActiveXObject.
Пробую создать следующим кодом

            try {
                xmlhttp = new ActiveXObject("MSXML2.ServerXMLHTTP.6.0");
                xmlhttp.setOption(2, 13056); //SXH_OPTION_IGNORE_SERVER_SSL_CERT_ERROR_FLAGS
            } catch (e) {
                try {
                    xmlhttp = new ActiveXObject("Msxml2.XMLHTTP.5.0");
                    xmlhttp.setOption(2, 13056); //SXH_OPTION_IGNORE_SERVER_SSL_CERT_ERROR_FLAGS
                } catch (E) {
                    xmlhttp = false;
                }

Объект не создается. В Чем может быть проблема?

Нравится

8 комментариев

Какая ошибка то? Невозможно создание объекта сервером программирования объектов? Значит COM не зарегистрирован в системе.
Переменная не определена? Напишите var xmlhttp = new ActiveXObject("MSXML2.ServerXMLHTTP.6.0");

А, и если вы это делаете из браузера - то по умолчанию насколько я помню браузер запрещает создавать ActiveX объекты. Необходимо отдельно включать такую опцию.

код ошибки

Uncaught ReferenceError: ActiveXObject is not defined SOAPClient.js:183
user: Supervisor/7f3b869f-34f3-4f20-ab4d-7480a5fdf647
 file: http://softex-iis:8896/0/configuration/c1a08ef0172dd11fc04cad296e761a3e/SOAPClient.js
 line: 183
 message: Uncaught ReferenceError: ActiveXObject is not defined 
 date: Fri Sep 19 2014 15:25:30 GMT+0400 (Московское время (зима)) 

new ActiveXObject работает только в IE и только под Windows.

Тогда есть ли возможность отключить проверку SSL сертификата у XMLHttpRequest?

Я не в курсе вашей задачи, но объект нужно создавать так:

xmlhttp=new XMLHttpRequest();

а не так

xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

http://www.w3schools.com/xml/xml_http.asp

Объект сейчас так и создан.

try {
 
                if (window.XMLHttpRequest) {
                    var req = new XMLHttpRequest();
                    // some versions of Moz do not support the readyState property and the onreadystate event so we patch it!
                    if (req.readyState == null) {
                        req.readyState = 1;
                        req.addEventListener("load",
                            function () {
                                req.readyState = 4;
                                if (typeof req.onreadystatechange == "function")
                                    req.onreadystatechange();
                            },
                            false);
                    }
                    return req;
                }
                if (window.ActiveXObject)
                    return new ActiveXObject(SOAPClient._getXmlHttpProgID());
            }
            catch (ex) {
            }
            throw new Error("Your browser does not support XmlHttp objects");

У ActiveX есть метод .setOption(2, 13056) который отключает проверку SSL сертификатов.
Есть ли аналог для объекта созданного следующим образом
var req = new XMLHttpRequest();

Поискал в интернете - вроде как нет.

Показать все комментарии

Добрый день, коллеги!

Пытаюсь выполнить простой скрипт (файл test.js):

var Connector = new ActiveXObject('TSWindowLibrary.DskConnector');

в консоли ввожу:

cscript test.js

и получаю:

Невозможно создание объекта сервером программирования объектов

В какую сторону копать, где искать причину? (Win 7 64bit)

Нравится

13 комментариев

Здравствуйте.

Попробуйте в Террасофт Администраторе создать новый сервис с типом скрипт, и вставить туда следующий код:

function Main()
   {
 
   	var Connector = new ActiveXObject('TSWindowLibrary.DskConnector');
   }

После этого, нажмите F9 для его выполнения.
Воспроизведется ли ошибка?

Ключевое тут х64!
Террасофт работает в режиме х32. Для того что бы ваш скрипт отработал нужно консоль запускать из папки SysWOW64

Дмитрий, да, в Террасофт Администраторе при попытке выполнить скрипт - та же ошибка.

"Евгений Либин" написал:

Ключевое тут х64!

нужно консоль запускать из папки SysWOW64


Спасибо, но на результат это никак не повлияло. Хотя, тоже склоняюсь к тому, что причина именно в x64 (проверил на x32 - там объект создается).

Похоже я нашел "где собака порылась" (с) :smile:
надо вызывать так

var Connector =  new ActiveXObject('TSDskObjectLibrary.DskConnector');

Это же вроде для версий TS до 3.4.0?

Нет, это как раз для 3.3.1

3.3.1 как раз до 3.4.0.

А, ну да :smile:

А какая версия у ТС?

ТС: 3.3.2.73

В администраторе сработал скрипт

var Connector =  new ActiveXObject('TSDskObjectLibrary.DskConnector');

но, извне, через

cscript test.js

по прежнему, та же ошибка.

P.S. Судя по выводу в консоли, сервер сценариев - версии 5.8

Вот сценарий проверки (это просто пример :smile:)
1. в папке D:\Temp\ делаете файл с названием test.js в теле которого

var Connector =  new ActiveXObject('TSDskObjectLibrary.DskConnector');

Потом в этой же директории делаете файл test.cmd c текстом

%WinDir%/SysWOW64/cscript.exe d:\Temp\Test.js

Запустите test.cmd.
У меня работает на х64

Евгений, спасибо! Работает :)

Показать все комментарии

Всем доброго времени суток!

Есть проблема с кодировкой txt-файла. Как изменить кодировку файла, т.к. после считывания данных файла выводит "квадратики":
пример кода:

function OpenTxtTemplate(Name) {
        var Dataset = GetSingleItemByCode('ds_Files','ds_Files');
        ApplyDatasetFilter(Dataset,'Link',Name,true);
        Dataset.Open();
        if (Dataset.IsEOF) {
                ShowInformationDialog('Template not found!');
                return null;
        }
        var File = LoadFileFromDatabase(Dataset.Values('ID'),Name,true);
        var Txt = new ActiveXObject("Scripting.FileSystemObject");
        //Txt.Visible = false;
        Txt.OpenTextFile(File, 1,false);
        var TextData = Txt.GetFile(File).OpenAsTextStream(1, true).ReadLine();
        debugger;
        Dataset.Close();
        return Txt;
}

Вот данные из VS:
Visual Studio

Подскажите, может быть есть другие способы получить данные с текстового файла?

Нравится

3 комментария

Здравствуйте Георгий!

В данном случае проблема в том, что FileSystemObject не поддерживает кодировку UTF8 (почему-то только UTF-16)

Поэтому есть два метода решения проблемы:

1. Изменить кодировку открываемого файла:

encoding

2. Работать с файлом через ADODB

var Stream = new ActiveXObject('ADODB.Stream');

Stream.Open
Stream.getFile(File).OpenAsTextStream(1, true).ReadLine()
Stream.CharSet = "UTF-8"

Спасибо, Анна!
Буду пробовать.

Анна, спасибо за рекомендации, немного доработал Ваш код:

function OpenTxtTemplate(File) {   	
	var Stream = new ActiveXObject('ADODB.Stream');
 	Stream.Open();
	Stream.Type = 2;
	Stream.CharSet = "UTF-8"
	Stream.LoadFromFile(File);
	var str = Stream.ReadText(-1);
}
Показать все комментарии

Данное сообщение будет полезно всем, кто занимается экспортом в Excel, особенно при выгрузке больших объемов данных.

Сам принцип довольно прост - формируем двухмерный вариантный массив, указываем область в Excel, куда необходимо его разместить и выгружаем. Самой проблемной остается задача заполнения массива. Для выгрузки из Delphi есть множество примеров/ Привожу один из них:

Но как сделать то же самое, только на языке JavaScript в конфигурации Terrasoft CRM и какая при этом будет скорость?

Привожу пример кода:

function Main() {
      var Excel = new ActiveXObject('Excel.Application');
      var Workbook = Excel.Workbooks.Add();
      var Sheet = Workbook.Sheets.Add();
      var StartRowNumber = 1;
      var StartColNumber = 1;
      var RowsCount = 10000;
      var ColumnsCount = 200;
      var Range = GetRangeObject(RowsCount, ColumnsCount);
      for (var X = 1; X = RowsCount; X++) {
            for (var Y = 1; Y = ColumnsCount; Y++) {
                  Range.Value(X, Y) = X * Y;
            }
      }
      var TopLeftRangeValue = GetRangeValue(StartRowNumber, StartColNumber);
      var BottomRightRangeValue = GetRangeValue(StartRowNumber + RowsCount - 1,
            StartColNumber + ColumnsCount - 1);
      Log.Write(1, 'Начало вставки записей в диапазон "' + TopLeftRangeValue +
            ':' + BottomRightRangeValue + '" = ' + RowsCount * ColumnsCount);
      Sheet.Range(TopLeftRangeValue, BottomRightRangeValue) =
            Range.ValuesAsArray;
      Log.Write(1, 'Конец вставки записей');
      Excel.Visible = true;
}

Для запуска в скрипт необходимо включить скрипт scr_UserReportCommon в котором находятся функции GetRangeValue() и GetRangeObject().
Функцию GetRangeValue нужно заменить на новую:
function GetRangeValue(RowNumber, ColumnNumber) {
      if ((RowNumber 1) || (ColumnNumber 1)) {
          return false;
      }
      var MaxCharNumber = 26;
      if (ColumnNumber > MaxCharNumber) {
            var FloorValue = Math.floor((ColumnNumber - 1)/MaxCharNumber);
            var FirstChar = String.fromCharCode(64 + FloorValue);
            var ColumnNumber = ColumnNumber - FloorValue * MaxCharNumber;
      } else {
            var FirstChar = '';
      }
      var RangeColumn = FirstChar + String.fromCharCode(64 + ColumnNumber);
      return RangeColumn + RowNumber;
}

Принцип действия следующий:
1) Создаем массив необходимых размеров:
      var Range = GetRangeObject(RowsCount, ColumnsCount);

2) Заполняем массив данными:
      for (var X = 1; X = RowsCount; X++) {
            for (var Y = 1; Y = ColumnsCount; Y++) {
                  Range.Value(X, Y) = X * Y;
            }
      }

3) Определяем адрес левой верхней и правой нижней ячеек по номерам строки и колонки (например, получаем следующие значения "A1", "GR10000"):
      var TopLeftRangeValue = GetRangeValue(StartRowNumber, StartColNumber);
      var BottomRightRangeValue = GetRangeValue(StartRowNumber + RowsCount - 1,
            StartColNumber + ColumnsCount - 1);

4) И самое главное - запускаем вставку данных из массива:
      Sheet.Range(TopLeftRangeValue, BottomRightRangeValue) =
            Range.ValuesAsArray;

При запуске выводит в лог следующее сообщение:
[09.03.04 09.50.32.342] (W) Начало вставки записей в диапазон "A1:GR10000" = 2000000
[09.03.04 09.50.36.628] (W) Конец вставки записей

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

При выгрузке старайтесь, чтобы объем размер области совпадал с размером массива.
И не забывайте, что в Excel существуют ограничения на количество строк и колонок в листе - строк не более 65536, а колонок - не более 256.

Нравится

Поделиться

5 комментариев

Не совсем так. В последней версии Excel колонок и строк может быть больше. Отсюда важный момент - при работе с очень большими файлами вариантный массив может не создасться, если создавать его по всей используемой области. Пишу просто потому что сам один раз на такое нарвался :)

Думаю, что при работе с большими объемами данных могут быть проблемы, которые, связаны с ограниченными ресурсами машины (например, памяти). В этом случае можно разделять массив данных на несколько более мелких блоков, каждый из которых необходимо будет вставлять в Excel отдельно.

Одним из быстрых способов также будет простой экспорт в csv формат

Интересно, а как можно организовать если на этапе создание объекта Range не известно количество строк?

И все же одним из быстрых способов будет простой экспорт в csv формат. Или же можно формировать результат непосредственно в формате Open XML для последних версий MS Office. Хотя с Open XML конечно сложнее.

Показать все комментарии