1 (изменено: lammv, 2015-01-13 18:00:39)

Тема: VBS:Копирование данных из таблицы для создания и использования массива

Есть таблица данных из 10 столбцов и N строк. В данном случае 11 строк. 


1    3345632           261    4315875    1    æåâ     3400    àìòã            UPH28
2    3345632           261    4536033    1    éç'     3400    àìòã             UPH28
1    3345639  2400    311     52365      2    éç'     3400    ãîéèøé          UPH28
2    3345639  2400    311     56754      2    éç'     3400    ãîéèøé          UPH28
3    3345639  2400    311     3363801    2    éç'     3400    ãîéèøé          UPH28
4    3345639  2400    311     4315875    1    æåâ     3400    ãîéèøé          UPH28
1    3345742           261    3061264    1    éç'      3400    àìëñ            UPH28
2    3345742           261    3276995    7    ì'        3400    àìëñ           UPH28
3    3345742           261    4315875    1    æåâ      3400    àìëñ            UPH28
4    3345742           261    5002031    1    éç'      3400     àìëñ            UPH28
5    3345742           261    5002033    1    éç'      3400     àìëñ            UPH28

Задача:
Создать массив по указанной таблице данных.
Необходимо внести в массив не всю таблицу, а только следующие столбцы:
1,2,3,4,5,6,8  (слева направо)

Пояснения:
VBScript.
Windows 7 - нет прав администратора. Word 2010, Excel 2010.
Буквенные столбцы не отображаются корректно (Unicode) и значения не имеют.
Предположим, что количество строк в таблице может быть не более 99.
Обратите внимание, что данная таблица содержит 3 подтаблицы (видно по первому и второму столбцам). Т.е. в данном случае в скрипте будет использоваться 3 цикла (что также должно быть отражено в массиве данных)
Цель скрипта автоматизировать работу некой Главной Программы, методом иммитации нажатия клавиш и подстановки данных из указанной таблицы.

Скрипт должен запускаться следующим образом:
1. В Эксель выделяются необходимые строки.
2. "Горячими" клавишами запускается скрипт, который производит иммитацию нажатия клавиш CTRL+C и копирует всю таблицу в буфер обмена.

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

Следует сказать, что скрипт без использования массива уже написан. Ввод данных в нем производится последовательным копираванием элементов второго столбца. В данном случае: первого, третьего и седьмого элементов (3345632, 3345639 3345742). Для выхода из цикла ввода данных, в буфер обмена копируется любое не семизначное число из таблицы.
Массив arr4() пока не используется.
Недостатком написанного скрипта является минимальное количество необходимых данных.



Option Explicit

Dim WshShell, oRegExp, sLine, LastLine, WshExec, Number, n7, n4
Dim arr7(): redim arr7(0)
Dim arr4(): redim arr4(0)

' creating link to an object
Set WshShell = WScript.CreateObject("WScript.Shell")

' Use a regular expression
set oRegExp = CreateObject("VBScript.RegExp")
oRegExp.IgnoreCase = True

n4 = -1
n7 = -1

' Clear Clipboard
CopyToClipBoard ""
LastLine = ""

' Cycle 
Do
    sLine = GetFromClipBoard()
    if (sLine <> LastLine) and (not isMatchInArray(sLine, arr7)) then
        if TestPattern (sLine, "^[0-9]{4,4}$") then
            n4 = n4 + 1
            redim preserve arr4(n4)
            arr4(n4) = sLine
        elseif TestPattern (sLine, "^[0-9]{7,7}$") then 
            n7 = n7 + 1
            redim preserve arr7(n7)
            arr7(n7) = sLine
        else
            Exit Do
        end if
        LastLine = sLine
    End if
    WScript.Sleep 800
Loop



WshShell.Run "MainProgram.exe", 1
WScript.Sleep 6500

for i = 1 to 2 : WshShell.SendKeys "%+"         : Next : WScript.Sleep 100

For each Number in arr7
    CopyToClipBoard Number
    WScript.Sleep 100

Dim i, a, q


'==========
'Program's body
'==========


Next

Dim s, oShell
for each Number in arr7      
s = s & Number & vbCrLf  
next

set oShell = WScript.CreateObject ("WScript.Shell")

oShell.Popup s, 6000




Function isMatchInArray(exNumber, arr)
    isMatchInArray = false
    For each Number in arr
        if exNumber = Number then isMatchInArray = true: exit For
    Next
End Function

Sub CopyToClipBoard(Data)
    Dim oShell: set oShell = CreateObject("WScript.Shell")
    Dim mshta: mshta = oShell.ExpandEnvironmentStrings("%windir%") & "\system32\mshta.exe"
    oShell.Run mshta & " ""vbscript:document.parentwindow.clipboardData.SetData(""text"",replace(""" & replace(Data," ","$#@!~%") & """,""$#@!~%"",chr(32)))&close()""",2,true
End Sub

' Checking the variable for matching a regular expression
Function TestPattern(Variable, Pattern)
    oRegExp.Pattern = Pattern
    TestPattern = CBool(oRegExp.Test(Variable))
End Function

Function GetFromClipBoard()
    GetFromClipBoard = CreateObject("htmlfile").ParentWindow.ClipboardData.GetData("text")
End Function    


Искренне благодарю всех за помощь.

2

Re: VBS:Копирование данных из таблицы для создания и использования массива

Решение созрело:


Set objExcel = CreateObject("Excel.Application")
Set objWorkbook = objExcel.Workbooks.Open _
    ("d:\1\file.xlsx")

' i - row
' j - column
i = 1
Dim array1(99,7), i,j
Do Until objExcel.Cells(i,1).Value = ""
 For j = 1 To 7
        If IsNull( objExcel.Cells(i, j).Value ) Then
   array1( i, j ) = ""
        Else
            array1( i, j ) = objExcel.Cells(i, j).Value
        End If
 Next
    i = i + 1
Loop
objExcel.Quit
'  Output of an array's element 
wscript.echo array1(2,7)

1. Как выполнить ту же задачу, но не из файла file.xlsx, а прямо из буфера обмена. Т.е. предполагается, что таблица данных находится уже в буфере обмена, а не в указанном файле эксель.

2. Путаюсь в синтаксисе. Как вывести сообщением весь массив с помощью MsgBox, а не только его отдельные элементы: "wscript.echo array1(2,7)"

3

Re: VBS:Копирование данных из таблицы для создания и использования массива

1. Как выполнить ту же задачу, но не из файла file.xlsx, а прямо из буфера обмена. Т.е. предполагается, что таблица данных находится уже в буфере обмена, а не в указанном файле эксель.

Никак. С буфером обмена можно работать только как с буфером обмена. И только. Посему — открыть Excel, добавить Рабочую книгу, вставить содержимое буфера обмена на Рабочий лист. Далее — по написанному.

2. Путаюсь в синтаксисе. Как вывести сообщением весь массив с помощью MsgBox, а не только его отдельные элементы: "wscript.echo array1(2,7)"

Сформировать строку. Например:

+ открыть спойлер
Option Explicit

Dim arrSomeValues(2, 3)
Dim i, j

Dim strLine


' Произвольно заполняем массив
Randomize Timer

For i = LBound(arrSomeValues, 1) To UBound(arrSomeValues, 1)
    For j = LBound(arrSomeValues, 2) To UBound(arrSomeValues, 2)
        arrSomeValues(i, j) = Int(100 * Rnd)
    Next
Next

' Формируем строку
strLine = ""

strLine = strLine & vbTab & "|"

For j = LBound(arrSomeValues, 2) To UBound(arrSomeValues, 2)
    strLine = strLine & vbTab & CStr(j)
Next

strLine = strLine & vbLf & String(8 * (UBound(arrSomeValues, 2) + 2), "=") & vbLf

For i = LBound(arrSomeValues, 1) To UBound(arrSomeValues, 1)
    strLine = strLine & CStr(i) & vbTab & "|"
    
    For j = LBound(arrSomeValues, 2) To UBound(arrSomeValues, 2)
        strLine = strLine & vbTab & arrSomeValues(i, j)
    Next
    
    strLine = strLine & vbLf
Next

MsgBox strLine

WScript.Quit 0

Но проще работать под консольным «cscript.exe» и просто делать вывод в консоль в виде:

+ открыть спойлер
Option Explicit

Dim arrSomeValues(2, 3)
Dim i, j


' Произвольно заполняем массив
Randomize Timer

For i = LBound(arrSomeValues, 1) To UBound(arrSomeValues, 1)
    For j = LBound(arrSomeValues, 2) To UBound(arrSomeValues, 2)
        arrSomeValues(i, j) = Int(100 * Rnd)
    Next
Next

' Формируем строку
For j = LBound(arrSomeValues, 2) To UBound(arrSomeValues, 2)
    WScript.StdOut.Write vbTab & CStr(j)
Next

WScript.StdOut.WriteLine
WScript.StdOut.WriteLine String(8 * (UBound(arrSomeValues, 2) + 2), "=")

For i = LBound(arrSomeValues, 1) To UBound(arrSomeValues, 1)
    WScript.StdOut.Write CStr(i) & vbTab & "|"
    
    For j = LBound(arrSomeValues, 2) To UBound(arrSomeValues, 2)
        WScript.StdOut.Write vbTab & arrSomeValues(i, j)
    Next
    
    WScript.StdOut.WriteLine
Next

WScript.Quit 0

4

Re: VBS:Копирование данных из таблицы для создания и использования массива

Перечитал первый пост. Непонятно, зачем нужен массив, промежуточная таблица, буфер обмена. Также непонятно это:

Для выхода из цикла ввода данных, в буфер обмена копируется любое не семизначное число из таблицы.

Я бы просто использовал библиотеку AutoItX3.dll.

P.S. lammv, по поводу поста в личку: предлагаю Вам изложить подробности в письме.

5 (изменено: lammv, 2015-01-24 21:20:34)

Re: VBS:Копирование данных из таблицы для создания и использования массива

Я бы просто использовал библиотеку AutoItX3.dll.

Пока невозможно, т.к. нет прав администратора.

Непонятно, зачем нужен массив, промежуточная таблица, буфер обмена


Все очень просто. Имеются большое количество данных в окне некой программы (исходная таблица в первом посте), которые не имеет смысла вводить через диалоговые окна. Проще выделить их в окне указанной программы, затем скопировать в буфер обмена и передать в vbs script, где и предлагается их обработать, посредством создания массива данных.

Также непонятно это:
Для выхода из цикла ввода данных, в буфер обмена копируется любое не семизначное число из таблицы.


Для выхода из цикла ввода данных. Т.е. сначала запускается скрипт. Цикл ожидает копирование данных в буфер обмена.
Копируем данные в буфер обмена. После этого необходимо "сообщить" скрипту, что ввод данных завершен. Для этого копируем в буфер обмена любое НЕ семизначное число из окна указанной программы(семизначное число - это данные для работы скрипта). Ничего оригинальнее не придумал, но так работал старый скрипт ( без массива ).

P.S. аlexii. Благодарю Вас. Обязательно составлю письмо с пояснениями.