Вверх ↑
Ответов: 1133
Рейтинг: 81
#1: 2014-09-20 15:56:46 ЛС | профиль | цитата
Доброго всем времени суток.
На днях понадобилось из HiAsm запустить excel и выполнить специфический макрос.
Для своих целей выбрал схему Леонид
WorkExcel.sha


Add(MainForm,12929222,147,75)
{
Left=20
Top=105
Width=746
Height=380
Caption="Excel: Чтение/Запись"
}
Add(Button,9204510,329,208)
{
Left=40
Top=10
Width=85
Caption="Открыть файл"
link(onClick,8012480:doExecute,[])
}
Add(Button,13032804,378,432)
{
Left=40
Top=40
Width=85
Caption="Закрыть Excel"
link(onClick,11962879:doClose,[(470,438)(470,256)])
}
Add(ODialog,8012480,378,208)
{
link(onExecute,11962879:doOpen,[])
}
Add(Edit,12495670,826,75)
{
Left=490
Top=110
Width=120
Color=-16777201
Text="True"
}
Add(Button,16209388,91,96)
{
Left=630
Top=325
Width=95
Caption="Выход"
link(onClick,12929222:doClose,[])
}
Add(Memory,1424219,770,75)
{
Default=String(True)
link(onData,12495670:doText,[])
}
Add(Edit,13509768,595,201)
{
Left=10
Top=235
Width=480
}
Add(Label,10777460,826,33)
{
Left=495
Top=90
Width=112
Height=17
Caption="Видимость на экране"
}
Add(Edit,16744919,378,75)
{
Left=145
Top=30
Width=465
Text="C:\Documents and Settings\Леонид\Мои документы\макрос1.xls"
}
Add(VBJScript,11962879,483,208)
{
WorkPoints=#6:doOpen|7:doSheet|7:doWrite|14:doWriteAddress|11:doWriteData|6:doRead|7:doClose|8:doMacros|
EventPoints=#6:onData|7:onData1|7:onError|
VarPoints=#7:VarData|8:VarArray|
DataPoints=#5:Data1|5:Data2|5:Data3|5:Data4|5:Data5|5:Data6|7:Visible|
Script=#15:Option Explicit|37:'Глобальные переменные в этом скрипте|80:Dim Datas1 'FullFileName Объявляем переменную путь и имя файла.|80:Dim Datas2 'Sheet Объявляем переменную имя листа.|80:Dim Datas3 'WriteData Объявляем переменную для записи в Excel.|80:Dim Datas4 'Row Объявляем переменную строка.|80:Dim Datas5 'Column Объявляем переменную столбец.|80:Dim Datas6 'Объявляем переменную Имя Макроса.|80:Dim xlVisible 'Объявляем переменную видимость.|80:Dim xlReadData 'Объявляем переменную для чтения из Excel.|80:Dim xlReadArray 'Объявляем переменную для чтения массива.|80:Dim xlBook 'Объявляем объектную переменную для открытия книги Excel.|80:Dim FSO 'Объявляем объектную переменную для проверки открываемого файла.|0:|27:Function doWork(Data,Index)|0:|80: Datas1 = Sys.Data1 'Читаем с верхней точки путь и имя файла.|80: Datas2 = Sys.Data2 'Читаем с верхней точки имя листа.|80: Datas3 = Sys.Data3 'Читаем с верхней точки имя данные.|80: Datas4 = Sys.Data4 'Читаем с верхней точки № строки.|80: Datas5 = Sys.Data5 'Читаем с верхней точки № столбца.|80: Datas6 = Sys.Data6 'Читаем с верхней точки имя макроса.|80: xlVisible = Sys.Visible 'Читаем с верхней точки признак видимости Excel.|0:|18: Select Case Index|80: Case "doWrite" 'Адрес и данные берутся с верхних точек.|58: xlBook.ActiveSheet.Cells(Datas4,Datas5).Value = Datas3|17: xlReadData=""|15: Case "doRead"|80: 'Устанавливаем Адрес ячейки по идеологии HiAsm: сначала сверху.|36: If Datas4>=1 And Datas5>=1 Then|80: xlReadData = xlBook.ActiveSheet.Cells(Datas4,Datas5).Value 'Читаем ячейку.|0:|80: Else 'Затем устанавливаем Адрес ячейки из потока слева.|34: If Data="" Or Data=NULL Then|80: 'Если нет никакого адреса: выдаём пустую строку.|22: xlReadData =""|0:|80: Else 'У меня VBScript принимает Число только с запятой,|80: Data = Replace(CStr(Data),".",",") 'поэтому меняем точки на запятые.|19: Dim xlinStr|79: xlinStr=inStr(Data, ":") 'Ищем разделитель и|80: If xlinStr=0 Then 'проверяем, не Массив-ли это.|27: Data=CDbl(Data)|79: Datas4=Int(Data) 'Превращаем Real число в № строки|80: Datas5=CInt((Data-Datas4)*1000) 'и № столбца.|87: xlReadData = xlBook.ActiveSheet.Cells(Datas4,Datas5).Value 'Читаем ячейку.|0:|80: Else 'Ура-а, это массив!|80: xlReadArray = "" 'Сбрасываем предыдущий массив.|17: Dim I|17: Dim J|21: Dim xlLen|22: Dim xlData|21: Dim xlRow|22: Dim xlColm|27: xlLen=Len(Data)|40: xlData=Left(Data, xlinStr-1)|31: xlData=CDbl(xlData)|79: Datas4=Int(xlData) 'Превращаем Real число в № строки|80: Datas5=CInt((xlData-Datas4)*1000) 'и № столбца начало массива.|45: xlData=Right(Data, xlLen-xlinStr)|31: xlData=CDbl(xlData)|79: xlRow=Int(xlData) 'Превращаем Real число в № строки|80: xlColm=CInt((xlData-xlRow)*1000) 'и № столбца окончания массива.|79: If Datas4 =< xlRow And Datas5 =< xlColm Then 'Границы массива|79: For I = Datas4 To xlRow 'определены.|79: For J = Datas5 To xlColm 'Читаем ячейку и|80: 'присоединяем разделитель ";".|91: xlReadArray = xlReadArray & xlBook.ActiveSheet.Cells(I, J).Value & ";"|21: Next|79: xlReadArray = xlReadArray & vbCrLf 'Присоединяем символы|80: Next 'окончания строки.|0:|61: ElseIf Datas4 =< xlRow And Datas5 > xlColm Then|80: 'Правая граница не задана: читаем строки до первой пустой ячейки.|31: xlColm = Datas5|39: For I = Datas4 To xlRow|99: Do While (Not IsEmpty(xlBook.ActiveSheet.Cells(I, xlColm).Value) Or xlColm >256)|80: 'Читаем ячейку и присоединяем разделитель ";".|95: xlReadArray = xlReadArray & xlBook.ActiveSheet.Cells(I, xlColm).Value & ";"|39: xlColm = xlColm + 1|23: Loop|52: xlReadArray = xlReadArray & vbCrLf|33: xlColm = Datas5|20: Next|0:|61: ElseIf Datas4 > xlRow And Datas5 =< xlColm Then|80: 'Нижняя граница не задана: читаем столбцы до первой пустой ячейки.|26: J = Datas5|30: xlRow = Datas4|96: Do While (Not IsEmpty(xlBook.ActiveSheet.Cells(xlRow, J).Value) Or xlRow >65536)|43: For J = Datas5 To xlColm|95: xlReadArray = xlReadArray & xlBook.ActiveSheet.Cells(xlRow, J).Value & ";"|23: Next|52: xlReadArray = xlReadArray & vbCrLf|35: xlRow = xlRow + 1|28: J = Datas5|20: Loop|0:|60: ElseIf Datas4 > xlRow And Datas5 > xlColm Then|80:'Границы массива не определены: читаем столбцы и строки до первой пустой ячейки.|29: xlRow = Datas4|30: xlColm = Datas5|102: Do While (Not IsEmpty(xlBook.ActiveSheet.Cells(xlRow, Datas5).Value) Or xlRow >65536)|103: Do While (Not IsEmpty(xlBook.ActiveSheet.Cells(xlRow, xlColm).Value) Or xlColm >256)|99: xlReadArray = xlReadArray & xlBook.ActiveSheet.Cells(xlRow, xlColm).Value & ";"|39: xlColm = xlColm + 1|23: Loop|52: xlReadArray = xlReadArray & vbCrLf|33: xlColm = Datas5|35: xlRow = xlRow + 1|21: Loop|0:|80: Else 'Адреса странные, выдаём пустую строку.|32: xlReadArray = ""|20: End If|27: xlReadData = ""|16: End If|12: End If|80: Sys.onData1 xlReadArray 'Выдаём массив в поток на правую точку.|10: End If|0:|80: Case "doWriteAddress" 'Адрес и сверху и из потока слева, данные только сверху.|79: If Datas4<1 Or Datas5<1 Then 'Устанавливаем адрес|80: Data=CDbl(Data) 'согласно идеологии HiAsm.|79: Datas4=Int(Data) 'Превращаем Real число в № строки|124: Datas5=CInt((Data-Datas4)*1000) 'и № столбца. '|10: End If|60: xlBook.ActiveSheet.Cells(Datas4,Datas5).Value = Datas3|19: xlReadData=""|0:|80: Case "doWriteData" 'Данные и сверху и из потока слева, адрес только сверху.|79: If Datas3="" Or Datas3=NULL Then 'Устанавливаем данные|80: Datas3=Data 'согласно идеологии HiAsm.|10: End If|60: xlBook.ActiveSheet.Cells(Datas4,Datas5).Value = Datas3|19: xlReadData=""|0:|16: Case "doSheet"|79: If Datas2="" Or Datas2=NULL Then 'Устанавливаем данные|79: Datas2=Data 'согласно идеологии HiAsm.|10: End If|36: If Datas2="" Or Datas2=NULL Then|79: Datas2="Лист1" 'По умолчанию выбираем Лист1.|10: End If|80: xlBook.Worksheets(Datas2).Activate 'Активируем выбранный лист.|17: xlReadData=""|0:|16: Case "doMacros"|79: If Datas6="" Or Datas6=NULL Then 'Устанавливаем имя макроса|80: Datas6=Data 'согласно идеологии HiAsm.|10: End If|36: If Datas6="" Or Datas6=NULL Then|34: MsgBox "Нет имени макроса!"|8: Else|80: xlBook.Application.Run Datas6 'Запускаем макрос.|10: End If|15: Case "doOpen"|79: If Datas1="" Or Datas1=NULL Then 'Устанавливаем данные|80: Datas1=Data 'согласно идеологии HiAsm.|9: End If|35: If Datas1="" Or Datas1=NULL Then|80: Set xlBook = CreateObject("Excel.Sheet") 'По умолчанию создаём книгу Excel.|7: Else|58: Set FSO = CreateObject("Scripting.FileSystemObject") '|11: Dim Ext|32: Ext = GetAnExtension(Datas1)|31: If LCase(Ext) = "xls" Then|75: '--------------------------------------------------------------------|80: Set xlBook = GetObject(Datas1)'Вот так открываем существуюшую книгу Excel.|75: '--------------------------------------------------------------------|79: 'Set xlBook = CreateObject("Excel.Application") 'Или|79: 'xlBook.WorkBooks.Open Datas1 'так|75: '--------------------------------------------------------------------|9: Else|35: MsgBox "Это не книга Excel!"|11: End If|9: End If|79: xlVisible = Sys.Visible 'Читаем признак видимости|79: If (xlVisible="0" Or xlVisible="False") Then 'с верхней точки и|80: xlVisible=False 'корректируем его.|9: Else|21: xlVisible=True|11: End If|80: xlBook.Application.Visible = xlVisible 'Делаем Excel (не)видимым.|47: xlBook.Parent.Windows(1).Visible = xlVisible|16: xlReadData=""|16: Case "doClose"|80: xlBook.Application.Visible =True 'Делаем Excel видимым перед закрытием.|42: xlBook.Parent.Windows(1).Visible = True|80: xlBook.Save 'Сохраняем открытую книгу.|80: xlBook.Application.Quit 'Выходим из Excel.|80: Set xlBook = Nothing 'Очищаем объектную переменную.|71: Set FSO = Nothing ' --"--|0:|11: End Select|0:|80: Sys.onData xlReadData 'Выдаём данные в поток на правую точку.|12:End Function|80:'-------------------------------------------------------------------------------|80:Function GetVar(Data,Index) 'Выдаём данные на нижние точки.|20: Select Case Index|17: Case "VarData"|22: GetVar=xlReadData|18: Case "VarArray"|23: GetVar=xlReadArray|13: End Select|12:End Function|80:'-------------------------------------------------------------------------------|80:Function GetAnExtension(FileSpec) 'Определяем расширение файла (ищем *.xls).|23: On Error Resume Next|50: GetAnExtension = FSO.GetExtensionName(FileSpec)|99: If CStr(Err.Number) <> 0 Then call LogMsg(EventError, "Невозможно найти тип файла: " & FileSpec)|12:End Function|80:'-------------------------------------------------------------------------------|79:Sub LogMsg(intType, strMsg) 'Выводим сообщение об ошибках.|37: Sys.onError strMsg & ";" & intType|7:End Sub|
UseName=0
link(onData,13509768:doText,[(565,214)(565,207)])
link(onData1,15727698:doText,[(565,221)(565,298)])
link(onError,6121340:doMessage,[(560,228)(560,340)])
link(Data1,16744919:Text,[(489,147)(384,147)])
link(Data2,3014991:Text,[(496,137)(433,137)])
link(Data3,228017:Text,[(503,127)(482,127)])
link(Data4,2473051:Text,[(510,117)(531,117)])
link(Data5,2623683:Text,[(517,127)(580,127)])
link(Data6,11319171:Text,[(524,137)(629,137)])
link(Visible,12495670:Text,[(531,147)(832,147)])
}
Add(Edit,3014991,427,75)
{
Left=5
Top=110
Width=120
Text="Лист2"
}
Add(Label,10619288,427,33)
{
Left=35
Top=90
Width=70
Height=17
Caption="Имя Листа"
AutoSize=1
}
Add(Button,5907251,378,250)
{
Left=15
Top=140
Width=100
Caption="Выбрать лист"
link(onClick,11962879:doSheet,[(420,256)(420,221)])
}
Add(Label,4909046,378,33)
{
Left=255
Top=10
Width=175
Caption="Полный путь и имя файла Excel"
}
Add(Edit,228017,476,75)
{
Left=140
Top=110
Width=175
Text="12345"
}
Add(Edit,2473051,525,75)
{
Left=325
Top=110
Width=75
Text="4"
DataType=2
}
Add(Edit,2623683,574,75)
{
Left=410
Top=110
Width=70
Text="5"
DataType=2
}
Add(Label,10545967,476,33)
{
Left=175
Top=90
Width=120
Caption="Данные для записи"
Alignment=2
}
Add(Label,253247,525,33)
{
Left=325
Top=90
Width=70
Caption="№ Строки"
Alignment=2
}
Add(Label,12911951,574,33)
{
Left=410
Top=90
Width=65
Height=17
Caption="№ Столбца"
Alignment=2
}
Add(Button,6292086,280,334)
{
Left=405
Top=185
Width=110
Caption="Запись по адресу"
link(onClick,11589413:doData,[])
}
Add(Button,7228509,189,376)
{
Left=70
Top=185
Width=105
Caption="Запись по данным"
link(onClick,7035148:doData,[])
}
Add(Button,7145105,91,418)
{
Left=5
Top=315
Width=100
Caption="Чтение"
link(onClick,12106511:doData,[])
}
Add(Button,1565981,672,33)
{
Left=515
Top=140
Width=75
Caption="Видимость"
link(onClick,11827052:doNext,[])
}
Add(Counter,11827052,721,33)
{
Max=1
link(onNext,15493762:doCompare,[])
}
Add(If_else,15493762,770,33)
{
Op2=Integer(0)
link(onTrue,1424219:doClear,[(813,39)(813,73)(760,73)(760,88)])
link(onFalse,7803171:doClear,[(807,46)(807,68)(691,68)(691,88)])
}
Add(Memory,7803171,700,75)
{
Default=String(False)
link(onData,1424219:doValue,[])
}
Add(Edit,6406798,140,376)
{
Left=115
Top=315
Width=115
Text="1,001"
}
Add(DoData,12106511,140,418)
{
link(onEventData,11962879:doRead,[(460,424)(460,249)])
link(Data,6406798:Text,[])
}
Add(Label,7560814,140,334)
{
Left=65
Top=295
Width=195
Height=17
Caption="Адресы для чтения ячеек и массивов"
Alignment=2
}
Add(DoData,7035148,238,376)
{
link(onEventData,11962879:doWriteData,[(450,382)(450,242)])
link(Data,3721504:Text,[])
}
Add(Label,6371554,595,152)
{
Left=245
Top=220
Width=98
Caption="Данные из ячейки"
}
Add(Label,155232,329,250)
{
Left=550
Top=170
Width=95
Height=17
Caption="Адрес для записи"
Alignment=2
}
Add(Button,13901617,378,292)
{
Left=215
Top=140
Width=205
Caption="Запись сверху"
link(onClick,11962879:doWrite,[(430,298)(430,228)])
}
Add(DoData,11589413,329,334)
{
link(onEventData,11962879:doWriteAddress,[(440,340)(440,235)])
link(Data,4233882:Text,[])
}
Add(Label,13182988,238,292)
{
Left=205
Top=170
Width=105
Height=17
Caption="Данные для записи"
Alignment=2
}
Add(Edit,3721504,238,334)
{
Left=180
Top=185
Width=150
Text="12345"
}
Add(Edit,4233882,329,292)
{
Left=520
Top=185
Width=150
Text="1,001"
}
Add(Edit,15727698,595,292)
{
Left=10
Top=270
Width=480
}
Add(Label,8912243,595,250)
{
Left=230
Top=255
Width=107
Height=17
Caption="Данные из массива"
}
Add(Edit,11127277,595,376)
{
Left=500
Top=235
Width=230
}
Add(Edit,6780075,595,418)
{
Left=500
Top=270
Width=230
}
Add(Button,6164229,378,516)
{
Left=500
Top=295
Width=80
Caption="Данные снизу"
link(onClick,3288854:doEvent1,[])
}
Add(DoData,16710140,504,376)
{
link(onEventData,11127277:doText,[])
link(Data,11962879:VarData,[(510,316)(489,316)])
}
Add(DoData,648402,546,418)
{
link(onEventData,6780075:doText,[])
link(Data,11962879:VarArray,[(552,306)(496,306)])
}
Add(Hub,3288854,427,516)
{
link(onEvent1,16710140:doData,[(481,522)(481,382)])
link(onEvent2,648402:doData,[(502,529)(502,424)])
}
Add(Button,7721283,378,474)
{
Left=630
Top=140
Width=85
Caption="Макрос"
link(onClick,11962879:doMacros,[(474,480)(474,263)])
}
Add(Edit,11319171,623,75)
{
Left=620
Top=110
Width=110
Text=""
}
Add(Label,1953620,623,33)
{
Left=625
Top=90
Width=100
Caption="Имя Макроса"
AutoSize=1
Alignment=2
}
Add(Message,6121340,595,334)
{
}



После переписки с автором схема приобрела вид
With_Excel.sha

Add(MainForm,561567,168,126)
{
Width=289
Height=174
Caption="With_Excel"
Point(onClose)
link(onClose,1168498:doClose,[(326,153)(326,230)])
}
Add(Button,11796961,217,105)
{
Left=5
Top=10
Width=65
Caption="Open Excel"
link(onClick,420540:doExecute,[])
}
Add(Hub,9982022,315,105)
{
link(onEvent1,10946710:doClear,[(419,111)(419,132)])
link(onEvent2,1168498:doOpen,[(337,118)(337,195)])
}
Add(ODialog,420540,266,105)
{
Filter="Excel|*.xls"
link(onExecute,9982022:doEvent1,[])
}
Add(VBJScript,1168498,371,189)
{
@Hint=#16:Query SQL Server|
WorkPoints=#6:doOpen|7:doWrite|6:doRead|7:doSheet|8:doMacros|7:doClose|
EventPoints=#6:onRead|7:onCells|7:onError|6:onOpen|
Script=#9:Dim strIn|10:Dim strOut|10:Dim NumRow|10:Dim NumCol|5:Dim i|5:Dim j|14:Dim MyArrays()|12:Dim objExcel|0:|22:Sub doWork(Data,Index)|18: Select Case Index|15: Case "doOpen"|52: Set objExcel = CreateObject("Excel.Application")|52: Set objWorkbook = objExcel.Workbooks.Open (Data)|93: For i=1 To objWorkbook.Sheets.Count 'Листы начинаются не с "0", а с "1"|78: sys.onRead objWorkbook.Sheets(i).Name 'Выводим имя наружу |9: Next|18: sys.onRead 0 |16: sys.onOpen 1|142: Case "doRead" 'На вход подаётся строка, содержащая (разделитель -- точка с запятой): НомерСтроки;НомерКолонки;|22: strIn = CStr(Data)|28: i = InStr(1,strIn,";",0)|37: NumRow = CLng(Mid(strIn, 1, i-1))|33: NumCol = CLng(Mid(strIn,i+1))|61: strOut = objExcel.ActiveSheet.Cells(NumRow, NumCol).Value|27: sys.onCells strOut |162: Case "doWrite" 'На вход подаётся строка, содержащая (разделитель -- точка с запятой): НомерСтроки;НомерКолонки;ЗаписываемоеЗначение|22: strIn = CStr(Data)|28: i = InStr(1,strIn,";",0)|37: NumRow = CLng(Mid(strIn, 1, i-1))|30: j = InStr(i+1,strIn,";",0)|41: NumCol = CLng(Mid(strIn, i+1, j-i-1))|28: strIn = Mid(strIn, j+1)|58: objExcel.ActiveSheet.Cells(NumRow, NumCol).Value=strIn|20: sys.onRead strIn|93: Case "doSheet" 'На вход подаётся строка, содержащая имя Листа|32: objExcel.Sheets(Data).Select|44: objExcel.ActiveSheet.Cells(1, 1).Select |18: Case "doMacros"|22: objExcel.Run(Data)|17: Case "doClose"|17: objExcel.Quit|26: Set objExcel = Nothing|20: sys.onOpen 0 |11: End Select|0:|7:End Sub|
UseName=0
link(onRead,11782534:doCompare,[(414,195)(414,175)(365,175)(365,125)])
link(onOpen,4742625:doEvent,[])
}
Add(ComboBox,10946710,427,119)
{
Left=95
Top=10
Width=95
Height=21
Text="Выбрать лист"
DataType=1
Point(doSelect)
link(onClick,1168498:doSheet,[(466,132)(466,181)(354,181)(354,216)])
}
Add(If_else,11782534,371,119)
{
Type=5
Op2=Integer(0)
link(onTrue,10946710:doAdd,[])
link(onFalse,10946710:doSelect,[(408,132)(408,167)])
}
Add(LED,1408573,469,203)
{
Left=25
Top=45
}
Add(IndexToChanel,4742625,427,210)
{
link(onEvent1,1408573:doOff,[])
link(onEvent2,1408573:doOn,[])
}
Add(Button,14928612,217,217)
{
Left=20
Top=90
Caption="Macros"
link(onClick,4697646:doData,[])
}
Add(Edit,12846848,266,161)
{
Left=100
Top=90
Width=110
Text="GodHelp"
}
Add(DoData,4697646,266,217)
{
link(onEventData,1168498:doMacros,[])
link(Data,12846848:Text,[])
}

Во время тестирования оказалось что нужно обрабатывать всевозможные ошибки. Учитывая что программа должна работать без вмешательства человека, соответственно
программа должна отработать полностью независимо от ошибок и их количества. И в зависимости от полученного результата, либо разослать на мыло работников необходимые файлы, либо отчет об ошибках на мыло администратора.
Ниже приведена схема попыток.

Попытка
В схеме два файла, обычный и с, намеренно вызванной, ошибкой.
Что нужно?
Нужно чтобы схема отработала полностью, а не ждала действий пользователя. Также отключить вывод ошибок в скрипте запуска, или в самом макросе. Или же добавить некую обработку ошибок, которая бы не выводила никаких окошек подтверждения, а сигнал об ошибке на соответствующую точку скрипта.
------------ Дoбавленo в 15.56:
Частично решается добавлением в скрипт запуска строчки on error resume next
А как в скрипте запуска сделать вывод ошибок пока еще ковыряю
карма: 2

0
файлы: 1mc2.rar [20.5KB] [281]