Javascript and excel vba

JavaScript Functions With in VBA: The Merger

Include a reference to ‘Microsoft Script Control 1.0’ as explained below, before proceeding with further JavaScript tricks in this page.

  1. Goto Menu -> Tools -> Reference
  2. Search for “Microsoft Script Control 1.0’ in the listbox and enable it.

Only if this reference is included, the VBScript or JavaScript commands that you are going to code inside VBA will be executed.

Note: With this article, we are not going to execute any external VBS or JS file, instead we are going to make VBA to execute the Scripts within Excel itself.

Coding Scripts inside VBA

As per Microsoft documentation, a script can be executed within a VBA in 4 different methods that is explained in detail in this page. In our examples we are only going to use ‘Run’ & ‘Eval’ methods.

Sub JavaScript_in_VBA()
    'Go to Menu -> Tool -> References -> Microsoft Script Control 1.0 & Enable by Clicking it
    Dim jsObj As New ScriptControl
    Dim InputValue1 As Integer, InputValue2 As Integer, Result As Integer

    'Get Sample Parameters
    InputValue1 = ThisWorkbook.Sheets(1).Cells(1, 1)
    InputValue2 = ThisWorkbook.Sheets(1).Cells(1, 2)

    'Define Scripting Language
    jsObj.Language = "JScript"
    With jsObj

        'Add JavaScript Code to Script Control Object
        .AddCode "function xProduct(a,b) {return (a*b);}"

        'Execute Added Script & Get result
        Result = .Run("xProduct", InputValue1, InputValue2)
        'Result = .Eval("xProduct( 1, 2)")

    End With
    ThisWorkbook.Sheets(1).Cells(1, 3) = Result
End Sub

Sub VBScript_in_VBA()
    Dim vbsObj As New ScriptControl
    vbsObj.Language = "VBScript"

    With vbsObj
        .AddCode "function xGetDate() xGetDate = Date End Function"
        MsgBox .Run("xGetDate")
        MsgBox .Eval("xGetDate()")
    End With
End Sub

Why we Need a JavaScript or VBS within VBA?

Sometimes, we will find built in functions in other programming languages. It would be tough to change the whole application from one programming language to another just because the other has few advanced functions.

In these situations, these kind of inter operable techniques such as this JavaScript inside VBA would save lot of time and effort. For example, JavaScript has enhanced library routines to handle JSON data which is tough to manipulate within VBA. In such case, we can make use of this technique and refer JSON libraries within VBA.

Содержание

  1. Объектная модель JavaScript для Excel в надстройках Office
  2. Интерфейсы API Office.js для Excel
  3. Объектная модель для Excel
  4. Диапазоны
  5. Образец диапазона
  6. Диаграммы, таблицы и другие объекты данных
  7. Создание таблицы
  8. Создание диаграммы
  9. База данных из JavaScript для веб страницы из Excel на VBA модуле
  10. Смотрите видео: База данных из JavaScript для веб страницы из Excel на VBA модуле.
  11. Смотрите видео: База данных из JavaScript для веб страницы из Excel на VBA модуле.
  12. Learn How To Code JavaScript in VBA
  13. JavaScript Functions With in VBA: The Merger
  14. Coding Scripts inside VBA
  15. Why we Need a JavaScript or VBS within VBA?
  16. How can I use JavaScript within an Excel macro?
  17. Excel Macros with Javascript
  18. 2 Answers 2

Объектная модель JavaScript для Excel в надстройках Office

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

Сведения об асинхронном типе интерфейсов API Excel и принципах их работы с книгой см. в статье Использование модели API, зависящей от приложения.

Интерфейсы API Office.js для Excel

Надстройка Excel взаимодействует с объектами в Excel с помощью API JavaScript для Office, включающего две объектных модели JavaScript:

API JavaScript для Excel. Появившийся в Office 2016 API JavaScript для Excel предоставляет строго типизированные объекты, с помощью которых можно получать доступ к листам, диапазонам, таблицам, диаграммам и другим объектам.

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

Скорее всего, вы будете разрабатывать большую часть функций надстроек для Excel 2016 или более поздней версии с помощью API JavaScript для Excel, но вам также потребуются объекты из общего API. Например:

  • Context. объект Context представляет среду выполнения надстройки и предоставляет доступ к ключевым объектам API. Он состоит из данных конфигурации книги, например contentLanguage и officeTheme , а также предоставляет сведения о среде выполнения надстройки, например host и platform . Кроме того, он предоставляет метод requirements.isSetSupported() , с помощью которого можно проверить, поддерживается ли указанный набор обязательных элементов приложением Excel, в котором работает надстройка.
  • Document. Объект Document предоставляет метод getFileAsync() , позволяющий скачать файл Excel, в котором работает надстройка.

На рисунке ниже показано, когда можно использовать API JavaScript для Excel или общие API.

Объектная модель для Excel

Чтобы понять API-интерфейсы Excel, вы должны понимать, как компоненты рабочей книги связаны друг с другом.

  • Рабочая книга содержит одну или несколько рабочих листов.
  • Рабочий лист содержит коллекции тех объектов данных, которые присутствуют на отдельном листе, и предоставляет доступ к ячейкам с помощью объектов Range.
  • Range представляет группу смежных клеток.
  • Диапазоны используются для создания и размещения таблиц, диаграмм, фигур и других объектов визуализации данных или организации.
  • Рабочие книги содержат коллекции некоторых из этих объектов данных (таких как таблицы) для всей рабочей книги.

В API JavaScript для Excel нет объекта или класса Cell. Вместо этого API JavaScript для Excel определяет все ячейки Excel как объекты Range . Отдельные ячейки в пользовательском интерфейсе Excel преобразуются в объект Range с одной ячейкой в API JavaScript для Excel. Один объект Range также может содержать несколько смежных ячеек. Дополнительные сведения см. в статье Работа с ячейками с использованием API JavaScript для Excel.

Диапазоны

Диапазон — это группа непрерывных ячеек в рабочей книге. В надстройках обычно используется нотация в стиле A1 (например, B3 для отдельной ячейки в столбце B и строке 3 или C2:F4 для ячеек из столбцов с C по F и строк с 2 по 4) для определения диапазонов.

Диапазоны имеют три основных свойства: values , formulas , и format . Эти свойства получают или устанавливают значения ячеек, формулы для оценки и визуальное форматирование ячеек.

Образец диапазона

В следующем примере показано, как создавать записи продаж. Эта функция использует объекты Range для установки значений, формул и форматов.

В этом примере создаются следующие данные в текущем листе.

Диаграммы, таблицы и другие объекты данных

API JavaScript для Excel могут создавать и управлять структурами данных и визуализациями в Excel. Таблицы и диаграммы являются двумя наиболее часто используемыми объектами, но API поддерживают сводные таблицы, фигуры, изображения и многое другое.

Создание таблицы

Создавайте таблицы, используя заполненные данными диапазоны. Элементы управления форматированием и таблицами (например, фильтры) автоматически применяются к диапазону.

В следующем примере создается таблица с использованием диапазонов из предыдущего примера.

Использование этого примера кода на листе с предыдущими данными создает следующую таблицу.

Создание диаграммы

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

В следующем примере создается простая гистограмма для трех элементов, которая размещается на 100 пикселей ниже верхней части листа.

Выполнение этого примера на листе с предыдущей таблицей создает следующую диаграмму.

Источник

База данных из JavaScript для веб страницы из Excel на VBA модуле

Всем привет, в этой статье я покажу, как с помощью Excel можно формировать JS массивы на основе таблиц. Звучит как бред, однако в дальнейшем можно сохранить массив в js файл, изменить расширение файла на DB и полученную «базу данных» подключать к простой веб странице, можно использовать в Android приложении или расширении для браузера. Меняя содержимое файла можно изменять данные не затрагивая html код, и тут пригодится Excel, который возьмет на себя перевод данных из таблицы в массив. Разбор из файла в JSON будет происходить в веб странице.

Смотрите видео: База данных из JavaScript для веб страницы из Excel на VBA модуле.

Итак, сохраним книгу Excel с поддержкой макросов, работать будем с двумя листами, tab — таблица и test — лист с кнопкой и готовым результатом. В редакторе VBA добавим новый модуль, и внесем в него следующий код:

Привяжем кнопку к модулю и нажмем на нее. Полученные данные вставим в текстовый файл с текстом

между кавычками. Файл сохраняем как JS, но с расширением db.

В секции head веб страницы(я ипользовал bootstrap шаблон), добавим «базу данных» как если бы это был скрипт. Прим: при использовании уберите пробел перед левой кавычкой!

В секции body опишем таблицу для вывода данных и script , который будет формировать строки и столбцы на странице. Прим: при использовании уберите пробел перед левой кавычкой!

При запуске html страницы будет отображена таблица: заголовок Имя и Возраст и данные name и age .

Первый VBA модуль обладает одним недостатком: имена полей приходится указывать в коде и самих полей только два, данные начинаются с первой строки. Вторая версия модуля сама определяет имена полей и их количество, «шапка» таблицы в первой строке, данные начинаются со второй строки. Сделайте копии листов tab , test сохранив как tab2 , test2 , добавьте новый модуль, вставьте в него следующий код и присвойте кнопке Module2.

Данный код модуля позволяет автоматически определять количество строк и столбцов, названия заголовков шапки таблицы, которые будут впоследствии использованы для получаения данных. При этом код в html стрнице нормально работает и с русскими буквами: user.name и user.Имя распознаются одинаково.

На что еще хочу обратить внимание это кодировка страницы и файла «базы данных», они должны быть одинаковые, например UTF-8, для страницы указываем charset=utf8 , а файл test.db сохраняем в Notepad++, иначе вместо текста получатся «кракозябры».

Смотрите видео: База данных из JavaScript для веб страницы из Excel на VBA модуле.

Источник

Learn How To Code JavaScript in VBA

JavaScript Functions With in VBA: The Merger

Include a reference to ‘Microsoft Script Control 1.0’ as explained below, before proceeding with further JavaScript tricks in this page.

Please enable JavaScript

  1. Goto Menu -> Tools -> Reference
  2. Search for “Microsoft Script Control 1.0’ in the listbox and enable it.

Only if this reference is included, the VBScript or JavaScript commands that you are going to code inside VBA will be executed.

Note: With this article, we are not going to execute any external VBS or JS file, instead we are going to make VBA to execute the Scripts within Excel itself.

Coding Scripts inside VBA

As per Microsoft documentation, a script can be executed within a VBA in 4 different methods that is explained in detail in this page. In our examples we are only going to use ‘Run’ & ‘Eval’ methods.

Why we Need a JavaScript or VBS within VBA?

Sometimes, we will find built in functions in other programming languages. It would be tough to change the whole application from one programming language to another just because the other has few advanced functions.

In these situations, these kind of inter operable techniques such as this JavaScript inside VBA would save lot of time and effort. For example, JavaScript has enhanced library routines to handle JSON data which is tough to manipulate within VBA. In such case, we can make use of this technique and refer JSON libraries within VBA.

Источник

How can I use JavaScript within an Excel macro?

There’s a really cool diff class hosted by Google here:

I’ve used it before on a few web sites, but now I need to use it within an Excel macro to compare text between two cells.

However, it is only available in JavaScript, Python, Java, and C++, not VBA.

My users are limited to Excel 2003, so a pure .NET solution wouldn’t work. Translating the code to VBA manually would take too much time and make upgrading difficult.

One option I considered was to compile the JavaScript or Java source using the .NET compilers (JScript.NET or J#), use Reflector to output as VB.NET, then finally downgrade the VB.NET code manually to VBA, giving me a pure VBA solution. After having problems getting it to compile with any .NET compiler, I abandoned this path.

Assuming I could have gotten a working .NET library, I could have also used ExcelDna (http://www.codeplex.com/exceldna), an open-source Excel add-in to make .NET code integration easier.

My last idea was to host an Internet Explorer object, send it the JavaScript source, and calling it. Even if I got this to work, my guess is it would be dirt-slow and messy.

UPDATE: Solution found!

I used the WSC method described below by the accepted answer. I had to change the WSC code a little to clean up the diffs and give me back a VBA-compatible array of arrays:

I registered the WSC and it worked just fine. The code in VBA for calling it is as follows:

(I tried keeping a single global objWMIService and objDiff around so I wouldn’t have to create/destroy these for each cell, but it didn’t seem to make a difference on performance.)

I then wrote my main macro. It takes three parameters: a range (one column) of original values, a range of new values, and a range where the diff should dump the results. All are assumed to have the same number of row, I don’t have any serious error-checking going on here.

These next three lines speed up the update without botching the user’s preferred calculation mode later:

Erasing the previous diffs, if any, is important:

This test is a visual shortcut for my users so it’s clear when there’s no change at all:

Combine all the text together as the delta cell value, whether the text was identical, inserted, or deleted:

You have to set the value before starting the formatting:

Here’s the code that interprets the diffs and formats the delta cell:

There are some opportunities for optimization, but so far it’s working just fine. Thanks to everyone who helped!

Источник

Excel Macros with Javascript

I wish to manipulate excel spreadsheets using macros in Javascript rather than the default VBA. I can execute javascript code using the following VBA code

this enables me to execute arbitrary javascript, however I do not have access to the excel spreadsheet from within the javascript environment. Is there any way I can set and get worksheet values in the active worksheet from within javascript?

2 Answers 2

For people using Excel 2016 or later version, there is an Excel add-in called Funfun in the add-in store that actually allows you to write and run JavaScript code directly in Excel. And of course, your JavaScript code also has access to the data stored in the spreadsheet. Here is a screenshot of how it looks like in Excel 2016.

Well in the middle of the interface you have a section in which you could write JavaScript, CSS and HTML code. It is pretty much like a playground built into the Excel. But the Funfun also has an online editor in which you could test with your code. You could see it in the pic below. I also posted the link of the example in the first picture so you could play with.

What is special about the Funfun online editor is that it contains a ‘spreadsheet’ just like Excel. Though you can’t actually do any formatting in here, you could copy your data into the cells and test your code directly.

To use the data stored in the spreadsheet, all you need to do is to write some configuration in the short.io file of Funfun to tell JavaScript which area in the spreadsheet that contains your data. For example, in the example that I posted, all you need to write is

And in the JavaScript code, an object called $internal is used to read the data. So in order to read the data that stored in A2:B9, you need to write

And its done. You could go to the documentation of Funfun if you want to know more.

If you are satisfied with the result you achieved in the online editor, you could easily load the result into you Excel using the URL above. Of couse first you need to insert the Funfun add-in from Insert — My add-ins. Here are some screenshots showing how you could do this.

Disclosure: I’m a developer of Funfun

Источник

Всем привет, в этой статье я покажу, как с помощью Excel можно формировать JS массивы на основе таблиц… Звучит как бред, однако в дальнейшем можно сохранить массив в js файл, изменить расширение файла на DB и полученную «базу данных» подключать к простой веб странице, можно использовать в Android приложении или расширении для браузера. Меняя содержимое файла можно изменять данные не затрагивая html код, и тут пригодится Excel, который возьмет на себя перевод данных из таблицы в массив. Разбор из файла в JSON будет происходить в веб странице.

Итак, сохраним книгу Excel с поддержкой макросов, работать будем с двумя листами, tab — таблица и test — лист с кнопкой и готовым результатом. В редакторе VBA добавим новый модуль, и внесем в него следующий код:

Sub main()
Dim myCol, myRow As Integer
Dim name1, name2 As String
Dim namval

myRow = 4 'строки
myCol = 2 'столбцы

name1 = "name"
name2 = "age"

namval = Sheets("tab").Range(Sheets("tab").Cells(1, 1), Sheets("tab").Cells(myRow, myCol))
For j = 1 To myRow
Sheets("test").Cells(j, 1) = "{" & Chr(34) & name1 & Chr(34) & ":" & Chr(34) & namval(j, 1) & Chr(34) & "," & Chr(34) & name2 & Chr(34) & ":" & namval(j, 2) & "},"
If j = myRow Then
Sheets("test").Cells(j, 1) = "{" & Chr(34) & name1 & Chr(34) & ":" & Chr(34) & namval(j, 1) & Chr(34) & "," & Chr(34) & name2 & Chr(34) & ":" & namval(j, 2) & "}"
End If
Next j

myRow = WorksheetFunction.CountA(Sheets("tab").Range("A:A")) 'строки
myCol = WorksheetFunction.CountA(Sheets("tab").Range("A1:AAA1")) 'столбцы

MsgBox "строки: " & myRow & " столбцы " & myCol

End Sub

Привяжем кнопку к модулю и нажмем на нее. Полученные данные вставим в текстовый файл с текстом

var arr = [
//ваши данные
]; 

между кавычками. Файл сохраняем как JS, но с расширением db.

В секции head веб страницы(я ипользовал bootstrap шаблон), добавим «базу данных» как если бы это был скрипт. Прим: при использовании уберите пробел перед левой кавычкой!

< script src="/test.db">< /script>

В секции body опишем таблицу для вывода данных и script, который будет формировать строки и столбцы на странице. Прим: при использовании уберите пробел перед левой кавычкой!

< table class="table">
< thead>
< tr>
< th scope="col">Имя</th>
< th scope="col">Возраст</th>
< /tr>
< /thead>
< tbody>
< script>
for(x=0;x < arr.length;x++){
var serializedUser = JSON.stringify(arr[x]);
var user = JSON.parse(serializedUser);
document.write("< tr>< td>" + user.name + "< /td>< td>" + user.age + "< /td>< /tr>");
}
< /script>
< /tbody>< /table>

При запуске html страницы будет отображена таблица: заголовок Имя и Возраст и данные name и age.

Первый VBA модуль обладает одним недостатком: имена полей приходится указывать в коде и самих полей только два, данные начинаются с первой строки. Вторая версия модуля сама определяет имена полей и их количество, «шапка» таблицы в первой строке, данные начинаются со второй строки. Сделайте копии листов tab, test сохранив как tab2, test2, добавьте новый модуль, вставьте в него следующий код и присвойте кнопке Module2.

Sub main2()
Dim myCol, myRow, namCount As Integer
Dim name1, name2 As String
Dim namval, nam
Dim str0, str1, str2, str3, str4, mStr
str0 = "{" & Chr(34)
str1 = Chr(34) & ":" & Chr(34)
str2 = Chr(34) & "," & Chr(34)
str3 = "},"
str4 = "}"

'myRow = 5 'строки
'myCol = 2 'столбцы
myRow = WorksheetFunction.CountA(Sheets("tab2").Range("A:A")) 'строки
myCol = WorksheetFunction.CountA(Sheets("tab2").Range("A1:AAA1")) 'столбцы
namCount = WorksheetFunction.CountA(Sheets("tab2").Range("A1:N1")) 'количество столбцов
namval = Sheets("tab2").Range(Sheets("tab2").Cells(2, 1), Sheets("tab2").Cells(myRow, myCol)) 'значения таблицы
nam = Sheets("tab2").Range("A1:N1") 'шапка

For j = 2 To myRow
mStr = str0
For i = 1 To namCount
mStr = mStr & nam(1, i) & str1 & namval(j - 1, i) & str2
Next i

mStr = Left(mStr, Len(mStr) - 2)
mStr = mStr & str3
Sheets("test2").Cells(j - 1, 1) = mStr

If j = myRow Then
mStr = str0
For i = 1 To namCount
mStr = mStr & nam(1, i) & str1 & namval(j - 1, i) & str2
Next i

mStr = Left(mStr, Len(mStr) - 2)
mStr = mStr & str4
Sheets("test2").Cells(j - 1, 1) = mStr

End If
Next j

End Sub 

Данный код модуля позволяет автоматически определять количество строк и столбцов, названия заголовков шапки таблицы, которые будут впоследствии использованы для получаения данных. При этом код в html стрнице нормально работает и с русскими буквами: user.name и user.Имя распознаются одинаково.

На что еще хочу обратить внимание это кодировка страницы и файла «базы данных», они должны быть одинаковые, например UTF-8, для страницы указываем charset=utf8, а файл test.db сохраняем в Notepad++, иначе вместо текста получатся «кракозябры»….

Смотрите видео: База данных из JavaScript для веб страницы из Excel на VBA модуле.

Понравилась статья? Поделитесь ею с друзьями и напишите отзыв в комментариях!

 

Добрый день.  
Нужно в VBA запустить javaScript, который лежит в том же каталоге что и экселевский файл.  
При этом скрипт возвращает значение типа int, его нужно получить и записать в ячейку А1.  
Есть ли вообще такая возможность?  

  PS: желательно не открывать никаких браузеров(это я и так реализовать могу)

 

Натыкался на эту тему, но там они ни к чему не пришли

 

subtlety

Пользователь

Сообщений: 375
Регистрация: 01.01.1970

Почему же не пришли — пришли.  
Например вот так:  

     Sub asd()  
        Shell «Cmd.exe /C Start C:scr.js»  
   End Sub  

  работает.

 

> При этом скрипт возвращает значение типа int  
Как, кому возвращает?  
Допишите в скрипт запись этого значения в реестр или в файл, потом считывайте из VBA.

 

nerv

Пользователь

Сообщений: 3071
Регистрация: 22.12.2012

Большинству из форумчан знаком «Редактор VB» [Alt+F11].
Но что-то я совсем не слышал про «Редактор сценариев» [Alt+Shift+F11]. Работал ли кто в нем? На первый взгляд — html документ с поддержкой javascript.
Вопрос можно ли и если да то как писать скрипты на js в Excel?  
спасибо)

 

Hugo

Пользователь

Сообщений: 23249
Регистрация: 22.12.2012

Orbit3v1, я могу сказать про скрипт vbs — его можно запустить как угодно (макросом или вручную), и он сам может открыть нужный файл и поместить в него значение.  
Думаю, js тоже это должен уметь.  
Другой вариант — макрос запускает скрипт, тот отрабатыввает и помещает значение в clipboard, откуда его забирает тот же макрос.  

  Про «Редактор сценариев» [Alt+Shift+F11] ничего не скажу — использовал только для просмотра данных файла.

 

subtlety, спасибо получилось.

 

subtlety

Пользователь

Сообщений: 375
Регистрация: 01.01.1970

Пожалуйста!  
А как с этим    
«возвращает значение типа int, его нужно получить и записать в ячейку А1.»  
решили?

 

слэн

Пользователь

Сообщений: 5192
Регистрация: 16.01.2013

может проверить errorlevel после выполнения сценария?

 

subtlety

Пользователь

Сообщений: 375
Регистрация: 01.01.1970

Можно, конечно, но зачем (=  
Код-то простой и так понятно, сработал или нет.

 

слэн

Пользователь

Сообщений: 5192
Регистрация: 16.01.2013

я не про ваш код, а про скрипт — если он возвращает код, который можно считать errorlevel-ом, то его можно засунуть в переменную среды, а из vba считать..  

  но проще, конечно, переписать сам скрипт

 

subtlety

Пользователь

Сообщений: 375
Регистрация: 01.01.1970

Так я и думал! =)  
«если он возвращает код, который можно считать errorlevel-ом»  
А как это сделать? Ткнете в пример?

 

слэн

Пользователь

Сообщений: 5192
Регистрация: 16.01.2013

 

subtlety

Пользователь

Сообщений: 375
Регистрация: 01.01.1970

Как передать параметр из скрипта в errorlevel

 
 

слэн

Пользователь

Сообщений: 5192
Регистрация: 16.01.2013

WScript.quit(errorlevel);

 

Передал значение в макрос через реестр.  
Создал в реестре флаг того, что яваскрипт отработал и сделал запись. Когда этот флаг устанавливается считываю результат из реестра, куда была произведенна запись.  
Всем спасибо за помощь

 

слэн

Пользователь

Сообщений: 5192
Регистрация: 16.01.2013

как вариант, а то можно было и сразу в ячейку..

 

А не расскажите как?  

  Но мне в принципе не нужно его вставлять в ячеку, нужно получить результат функции и с ним дальше производить вычисления.

 

слэн

Пользователь

Сообщений: 5192
Регистрация: 16.01.2013

а зачем, собственно, вообще использовать связку?  
нельзя просто на vba переписать эту функцию?

 

слэн

Пользователь

Сообщений: 5192
Регистрация: 16.01.2013

или уж продолжать на яве..

 

Зачем — это очень интересный вопрос.  
Попросили создать прайслисты продукции.    
При этом цены на изделия нет, но есть формулы по которым их можно расчитать — около 70000,а находятся они в MSSQL. Формулы написаны на javascript, или на чем-то очень похожем.  
Прайслист они хотят видеть в excel.    
Для этого я в VBA динамически создаю javascript для каждой продукции, запускаю его, получаю цену и вставляю в  MSSQL, тем самым создавая связку продукция — цена.    
После этих махинаций можно уже и создать прайслист в excel.

 

слэн

Пользователь

Сообщений: 5192
Регистрация: 16.01.2013

можно пример? этого script-а

 

Выложу сегодня после 20:00, сейчас нет доступа к ним

 

subtlety

Пользователь

Сообщений: 375
Регистрация: 01.01.1970

#26

11.04.2012 18:24:58

«на javascript, или на чем-то очень похожем.»  
Может, JScript?  

  Вообще, зоопарк тот еще…

There’s a really cool diff class hosted by Google here:

http://code.google.com/p/google-diff-match-patch/

I’ve used it before on a few web sites, but now I need to use it within an Excel macro to compare text between two cells.

However, it is only available in JavaScript, Python, Java, and C++, not VBA.

My users are limited to Excel 2003, so a pure .NET solution wouldn’t work. Translating the code to VBA manually would take too much time and make upgrading difficult.

One option I considered was to compile the JavaScript or Java source using the .NET compilers (JScript.NET or J#), use Reflector to output as VB.NET, then finally downgrade the VB.NET code manually to VBA, giving me a pure VBA solution. After having problems getting it to compile with any .NET compiler, I abandoned this path.

Assuming I could have gotten a working .NET library, I could have also used ExcelDna (http://www.codeplex.com/exceldna), an open-source Excel add-in to make .NET code integration easier.

My last idea was to host an Internet Explorer object, send it the JavaScript source, and calling it. Even if I got this to work, my guess is it would be dirt-slow and messy.

UPDATE: Solution found!

I used the WSC method described below by the accepted answer. I had to change the WSC code a little to clean up the diffs and give me back a VBA-compatible array of arrays:

function DiffFast(text1, text2)
{
    var d = dmp.diff_main(text1, text2, true);
    dmp.diff_cleanupSemantic(d);
    var dictionary = new ActiveXObject("Scripting.Dictionary"); // VBA-compatible array
    for ( var i = 0; i < d.length; i++ ) {
    dictionary.add(i, JS2VBArray(d[i]));
    }
    return dictionary.Items();
}

function JS2VBArray(objJSArray)
{
    var dictionary = new ActiveXObject("Scripting.Dictionary");
    for (var i = 0; i < objJSArray.length; i++) {
        dictionary.add( i, objJSArray[ i ] );
        }
    return dictionary.Items();
}

I registered the WSC and it worked just fine. The code in VBA for calling it is as follows:

Public Function GetDiffs(ByVal s1 As String, ByVal s2 As String) As Variant()
    Dim objWMIService As Object
    Dim objDiff As Object
    Set objWMIService = GetObject("winmgmts:")
    Set objDiff = CreateObject("Google.DiffMatchPath.WSC")
    GetDiffs = objDiff.DiffFast(s1, s2)
    Set objDiff = Nothing
    Set objWMIService = Nothing
End Function

(I tried keeping a single global objWMIService and objDiff around so I wouldn’t have to create/destroy these for each cell, but it didn’t seem to make a difference on performance.)

I then wrote my main macro. It takes three parameters: a range (one column) of original values, a range of new values, and a range where the diff should dump the results. All are assumed to have the same number of row, I don’t have any serious error-checking going on here.

Public Sub DiffAndFormat(ByRef OriginalRange As Range, ByRef NewRange As Range, ByRef DeltaRange As Range)
    Dim idiff As Long
    Dim thisDiff() As Variant
    Dim diffop As String
    Dim difftext As String
    difftext = ""
    Dim diffs() As Variant
    Dim OriginalValue As String
    Dim NewValue As String
    Dim DeltaCell As Range
    Dim row As Integer
    Dim CalcMode As Integer

These next three lines speed up the update without botching the user’s preferred calculation mode later:

    Application.ScreenUpdating = False
    CalcMode = Application.Calculation
    Application.Calculation = xlCalculationManual
    For row = 1 To OriginalRange.Rows.Count
        difftext = ""
        OriginalValue = OriginalRange.Cells(row, 1).Value
        NewValue = NewRange.Cells(row, 1).Value
        Set DeltaCell = DeltaRange.Cells(row, 1)
        If OriginalValue = "" And NewValue = "" Then

Erasing the previous diffs, if any, is important:

            Erase diffs

This test is a visual shortcut for my users so it’s clear when there’s no change at all:

        ElseIf OriginalValue = NewValue Then
            difftext = "No change."
            Erase diffs
        Else

Combine all the text together as the delta cell value, whether the text was identical, inserted, or deleted:

            diffs = GetDiffs(OriginalValue, NewValue)
            For idiff = 0 To UBound(diffs)
                thisDiff = diffs(idiff)
                difftext = difftext & thisDiff(1)
            Next
        End If

You have to set the value before starting the formatting:

        DeltaCell.value2 = difftext
        Call FormatDiff(diffs, DeltaCell)
    Next
    Application.ScreenUpdating = True
    Application.Calculation = CalcMode
End Sub

Here’s the code that interprets the diffs and formats the delta cell:

Public Sub FormatDiff(ByRef diffs() As Variant, ByVal cell As Range)
    Dim idiff As Long
    Dim thisDiff() As Variant
    Dim diffop As String
    Dim difftext As String
    cell.Font.Strikethrough = False
    cell.Font.ColorIndex = 0
    cell.Font.Bold = False
    If Not diffs Then Exit Sub
    Dim lastlen As Long
    Dim thislen As Long
    lastlen = 1
    For idiff = 0 To UBound(diffs)
        thisDiff = diffs(idiff)
        diffop = thisDiff(0)
        thislen = Len(thisDiff(1))
        Select Case diffop
            Case -1
                cell.Characters(lastlen, thislen).Font.Strikethrough = True
                cell.Characters(lastlen, thislen).Font.ColorIndex = 16 ' Dark Gray http://www.microsoft.com/technet/scriptcenter/resources/officetips/mar05/tips0329.mspx
            Case 1
                cell.Characters(lastlen, thislen).Font.Bold = True
                cell.Characters(lastlen, thislen).Font.ColorIndex = 32 ' Blue
        End Select
        lastlen = lastlen + thislen
    Next
End Sub

There are some opportunities for optimization, but so far it’s working just fine. Thanks to everyone who helped!

Понравилась статья? Поделить с друзьями:
  • Java чтение word файла
  • Java create word document
  • Java таблица как в excel
  • Java api for word
  • Java сохранение в excel