Что нового

WinAPI.au3, Error: The requested action with this object has failed

CrazyDoc

Новичок
Сообщения
75
Репутация
2
Доброго дня. Сваял костыль для личных нужд - ловлю непонятную ошибку. Пожалуйста помогите понять:
скрипт
Код:
#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
Global $oWordApp = ObjCreate('Word.Application'), $bool=true
Local $IntDir=@ScriptDir&"\[abbr=AutoIt v3 is a freeware BASIC-like scripting language designed for automating  the Windows GUI and general scripting][abbr=AutoIt v3 is a freeware BASIC-like scripting language designed for automating  the Windows GUI and general scripting][abbr=AutoIt v3 is a freeware BASIC-like scripting language designed for automating  the Windows GUI and general scripting][abbr=AutoIt v3 is a freeware BASIC-like scripting language designed for automating  the Windows GUI and general scripting][abbr=AutoIt v3 is a freeware BASIC-like scripting language designed for automating  the Windows GUI and general scripting]AIt[/abbr][/abbr][/abbr][/abbr][/abbr].ini", $var
$var = FileOpenDialog("", @ScriptDir & "\", "(*.doc)", 1 + 4)
If @error Then
    MsgBox(4096, "", "Не выбрано ни одного файла")
	Exit
Else
    $var = StringReplace($var, "|", @CRLF)
EndIf

$oWordApp.visible = 1
$oWordApp.Documents.Open($var)

local $rows = $oWordApp.Activedocument.Tables(1).Rows.Count
Opt("GUIOnEventMode", 1)
While 1
   local $Hour=0, $var=0, $for=0, $for1=0, $i=0, $family=0, $hours=0, $hourswork=0, $Keys=0, $Items=0, $Items1=0, $oDict = ObjCreate('Scripting.Dictionary'), $oDict1 = ObjCreate('Scripting.Dictionary')
   GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")	;закрывает скрипт если окно, созданное в процессе, получило собитые $GUI_EVENT_CLOSE
   For $for=5 To $rows	;считывает необходимые столбцы в word документе, заполняет данными два две библиотеки - для лучшего перебора(первый столбец - фамилия, содержимое 
	  Sleep(10)	;может повторятся. второй - план в часах, третий - факт работ в часах)
	  $i=$oWordApp.Activedocument.Tables(1).Cell($for,6).Range.Text
	  $family=StringSplit($i, @CRLF,2)
	  $i=$oWordApp.Activedocument.Tables(1).Cell($for,7).Range.Text
	  $hours=StringSplit($i, @CRLF,2)
	  $i=$oWordApp.Activedocument.Tables(1).Cell($for,8).Range.Text
	  $hourswork=StringSplit($i, @CRLF,2)
	  For $for1=0 To UBound($family)-2	;перебор библиотек, заполнение двух массивов(здесь изначально был один двумерный массив - поэтому два двумерных с одинаковым 
		 If $oDict.Exists($family[$for1]) Then	;первым столбцом). если ключ библиотеки уже встречался в массиве - добавляется его значение, если нет - записывается 
			$oDict.Item($family[$for1]) = $oDict.Item($family[$for1])+$hours[$for1]	;новая ячейка массива
		 Else
			$oDict.Add($family[$for1], $hours[$for1])
		 EndIf
	  Next
	  For $for1=0 To UBound($family)-2
		 If $oDict1.Exists($family[$for1]) Then
			$oDict1.Item($family[$for1]) = $oDict1.Item($family[$for1])+$hourswork[$for1]
		 Else
			$oDict1.Add($family[$for1], $hourswork[$for1])
		 EndIf
	  Next
   Next
   $Keys = $oDict.Keys()
   $Items = $oDict.Items()
   $Items1 = $oDict1.Items()
   if $bool=true Then ; создается форма окна с выводимыми данными
	  GUICreate("Мой GUI", 188, 360, -1, -1, $WS_OVERLAPPEDWINDOW + $WS_POPUP, $WS_EX_TOPMOST)
	  GUISetState(@SW_SHOW)
	  local $Array1[UBound($Keys)][2], $ArrayGuiCtrlKeys[UBound($Keys)], $ArrayGuiCtrlItem[UBound($Keys)], $ArrayGuiCtrlItem1[UBound($Keys)]
   EndIf
	  For $for1=0 To UBound($Keys)-1
		 Sleep(10)
		 $Array1[$for1][0]=$Keys[$for1]
		 $Array1[$for1][1]=$Items[$for1]
		 If $bool==False Then 	;обновление выводимых данных и цвета фона при заданных условиях
			GUICtrlSetData($ArrayGuiCtrlItem[$for1],$Items[$for1])
			$Hour=IniRead($IntDir,"Set",$Array1[$for1][0],"1")
			If $Array1[$for1][1]==$Hour Then
			   GUICtrlSetBkColor($ArrayGuiCtrlItem[$for1], 0xCCFFCC)
			Else
			   GUICtrlSetBkColor($ArrayGuiCtrlItem[$for1], 0xFF0000)
			EndIf
			GUICtrlSetData($ArrayGuiCtrlItem1[$for1],$Items1[$for1])
			If $Items[$for1]=$Items1[$for1] Then
			   GUICtrlSetBkColor($ArrayGuiCtrlItem1[$for1], 0xCCFFCC)
			Else
			   GUICtrlSetBkColor($ArrayGuiCtrlItem1[$for1], 0xFF0000)
			EndIf
		 EndIf
		 if $bool==true Then	; это здесь чтобы не писать еще один for
			$ArrayGuiCtrlKeys[$for1]=GUICtrlCreateLabel($Array1[$for1][0], 24, ($for1+1)*24)
			$ArrayGuiCtrlItem[$for1]=GUICtrlCreateLabel($Array1[$for1][1], 140, ($for1+1)*24)
			$ArrayGuiCtrlItem1[$for1]=GUICtrlCreateLabel($Array1[$for1][1], 164, ($for1+1)*24)
			GUICtrlSetBkColor(-1, 0xCCFFCC)
		 EndIf
	  Next
   $bool=False
   Sleep(100)
WEnd
$oWordApp.Quit


Func CLOSEClicked()
  $oWordApp.Quit
  Exit
EndFunc
ошибка
---------------------------
AutoIt Error
---------------------------
Line 5419 (File "C:\Users\s****\Documents\Планы и отчеты\2015\saprep1.3.exe"):


Error: The requested action with this object has failed.
---------------------------
ОК
---------------------------

Грешу на WinAPI т.к. добавление Sleep в блоке с обращением к word несколько увеличивает время работы до ошибки.

Ссылка на тему о библиотеке от Creator, ниже упоминаемую inververs, в архиве: https://opera-ac.net/index.php?topic=4522.0
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Нужно узнать строку в скрипте с этой ошибкой. Creator сделал программу, которая может показать что в строке 5419, но я не знаю где она. Можете поискать.
Или пусть ваш скрипт поработает без компиляции, когда возникнет такая ошибка, то покажет больше информации.
 
Автор
C

CrazyDoc

Новичок
Сообщения
75
Репутация
2
inververs сказал(а):
Нужно узнать строку в скрипте с этой ошибкой.
Вывод сообщения после ошибки на каждой строке думаю подойдет?
И к общим вопросам - возможно сразу подскажите общие ошибки составления? Что бросается в глаза, чего бы вы не стали делать никогда.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
CrazyDoc [?]
Вывод сообщения после ошибки на каждой строке думаю подойдет?
Да, так тоже можно.

Что бросается в глаза, чего бы вы не стали делать никогда.
Ну, то что вы работаете с объектами и нигде не используете IsObj это большая ошибка, в новых версиях Autoit будут проблемы.
 
Автор
C

CrazyDoc

Новичок
Сообщения
75
Репутация
2
Выдал компилятор:
$i=$oWordApp.Activedocument.Tables(1).Cell($for,6).Range.Text
$i=$oWordApp.Activedocument^ ERROR
>Exit code: 1 Time: 100.8

Пока что еще не понял в чем проблема... Да, версия [abbr=AutoIt v3 is a freeware BASIC-like scripting language designed for automating the Windows GUI and general scripting][abbr=AutoIt v3 is a freeware BASIC-like scripting language designed for automating the Windows GUI and general scripting]AIt[/abbr][/abbr] 14финал. Кстати на XP такой ошибки пока не видел - вылетает на семерке.

Нашел программу от Сreator, к сожалению, не помогла понять суть проблемы. Ссылка добавлена в шапку.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
А вам не подойдет стандартный WordUDF? Там есть функции чтения таблиц.

CrazyDoc [?]
Да, версия AIt 14финал
эта версия хочет правильных названий всех методов и свойств и в правильном регистре.
Вот правильные:
$oWordApp.Visible = True
ActiveDocument
Лучше вам заменить свои Activedocument на ActiveDocument итп
 

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
OffTopic:
inververs
эта версия хочет правильных названий всех методов и свойств и в правильном регистре
Не подтверждается
Код:
ConsoleWrite(@AutoItVersion & @CRLF)
$oSD = ObjCreate("Scripting.Dictionary")
$oSD.Item("1") = "1"
$oSD.iTEm("2") = "2"
$oSD.ITEM("3") = "3"
ConsoleWrite($oSD.Exists("1") &":"& $oSD.eXiStS("2") &":"& $oSD.EXISTS("3") & @CRLF)
ConsoleWrite($oSD.Item("1") &":"& $oSD.item("2") &":"& $oSD.ItEm("3") & @CRLF)
Код:
3.3.14.2
True:True:True
1:2:3
 
Автор
C

CrazyDoc

Новичок
Сообщения
75
Репутация
2
inververs сказал(а):
А вам не подойдет стандартный WordUDF? Там есть функции чтения таблиц.
Проблема в том что читает он всю таблицу в двумерный массив. Когда начинал - думал ей воспользоваться, но, чтобы получить информацию из нужных столбцов придется все равно пользоваться $oWordApp.ActiveDocument.Tables(1).Rows.Count - потому и решил уже все под одну гребенку писать. К тому же некоторые клетки объединены - непонятно как будет читать UDF.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
OffTopic:
Станно, я помню, что в какой то версии выше чем 3.3.12.0 не работали объекты именно из за не правильно названных методов
 
Автор
C

CrazyDoc

Новичок
Сообщения
75
Репутация
2
inververs сказал(а):
А вам не подойдет стандартный WordUDF? Там есть функции чтения таблиц.

Попробовал:
Код:
#include <Array.au3>
#include <MsgBoxConstants.au3>
#include <Word.au3>
#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

Global $bool=true
local $IntDir=@ScriptDir&"\Ait.ini"
local $var = FileOpenDialog("", @ScriptDir & "\", "(*.doc)", 1 + 4)
If @error Then
    MsgBox(4096, "", "Не выбрано ни одного файла")
	Exit
Else
    $var = StringReplace($var, "|", @CRLF)
EndIf
Local $oWord = _Word_Create()
Local $oDoc = _Word_DocOpen($oWord, $var, Default, Default, True)
;Local $asResult = _Word_DocTableRead($oDoc, 1, 1)
;_ArrayDisplay($asResult, "Word UDF: _Word_DocTableRead Example")
Opt("GUIOnEventMode", 1)
While 1
   local $Hour=0, $var=0, $for=0, $for1=0, $i=0, $family=0, $hours=0, $hourswork=0, $Keys=0, $Items=0, $Items1=0, $oDict = ObjCreate('Scripting.Dictionary'), $oDict1 = ObjCreate('Scripting.Dictionary')
   Local $asResult = _Word_DocTableRead($oDoc, 1, default)
   local $rows = $asResult[0][0]
   GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
   For $for=5 To $rows
	  $i=$asResult[$for][5]
	  $family=StringSplit($i, @CRLF,2)
	  $i=$asResult[$for][6]
	  $hours=StringSplit($i, @CRLF,2)
	  $i=$asResult[$for][7]
	  $hourswork=StringSplit($i, @CRLF,2)
	  ;_ArrayDisplay($family)
	  ;_ArrayDisplay($hours)
	  ;_ArrayDisplay($hourswork)
	  ;MsgBox(1,"",UBound($family)-2)
	  For $for1=0 To UBound($family)-1
		 ;_ArrayDisplay($family)
		 ;_ArrayDisplay($hours)
		 ;_ArrayDisplay($hourswork)
		 If $oDict.Exists($family[$for1]) Then
			$oDict.Item($family[$for1]) = $oDict.Item($family[$for1])+$hours[$for1]
			$oDict1.Item($family[$for1]) = $oDict1.Item($family[$for1])+$hourswork[$for1]
		 Else
			$oDict.Add($family[$for1], $hours[$for1])
			$oDict1.Add($family[$for1], $hourswork[$for1])
		 EndIf
	  Next
   Next
   $Keys = $oDict.Keys()
   $Items = $oDict.Items()
   $Items1 = $oDict1.Items()
   if $bool=true Then ; создается форма окна с выводимыми данными
	  GUICreate("Мой GUI", 188, 360, -1, -1, $WS_OVERLAPPEDWINDOW + $WS_POPUP, $WS_EX_TOPMOST)
	  GUISetState(@SW_SHOW)
	  local $Array1[UBound($Keys)][2], $ArrayGuiCtrlKeys[UBound($Keys)], $ArrayGuiCtrlItem[UBound($Keys)], $ArrayGuiCtrlItem1[UBound($Keys)]
   EndIf
	  For $for1=0 To UBound($Keys)-1
		 Sleep(10)
		 $Array1[$for1][0]=$Keys[$for1]
		 $Array1[$for1][1]=$Items[$for1]
		 If $bool==False Then 	;обновление выводимых данных и цвета фона при заданных условиях
			GUICtrlSetData($ArrayGuiCtrlItem[$for1],$Items[$for1])
			$Hour=IniRead($IntDir,"Set",$Array1[$for1][0],"1")
			If $Array1[$for1][1]==$Hour Then
			   GUICtrlSetBkColor($ArrayGuiCtrlItem[$for1], 0xCCFFCC)
			Else
			   GUICtrlSetBkColor($ArrayGuiCtrlItem[$for1], 0xFF0000)
			EndIf
			GUICtrlSetData($ArrayGuiCtrlItem1[$for1],$Items1[$for1])
			If $Items[$for1]=$Items1[$for1] Then
			   GUICtrlSetBkColor($ArrayGuiCtrlItem1[$for1], 0xCCFFCC)
			Else
			   GUICtrlSetBkColor($ArrayGuiCtrlItem1[$for1], 0xFF0000)
			EndIf
		 EndIf
		 if $bool==true Then	; это здесь чтобы не писать еще один for
			$ArrayGuiCtrlKeys[$for1]=GUICtrlCreateLabel($Array1[$for1][0], 24, ($for1+1)*24)
			$ArrayGuiCtrlItem[$for1]=GUICtrlCreateLabel($Array1[$for1][1], 140, ($for1+1)*24)
			$ArrayGuiCtrlItem1[$for1]=GUICtrlCreateLabel($Array1[$for1][1], 164, ($for1+1)*24)
			GUICtrlSetBkColor(-1, 0xCCFFCC)
		 EndIf
	  Next
   $bool=False
   Sleep(100)
WEnd
$oWordApp.Quit


Func CLOSEClicked()
  $oWordApp.Quit
  Exit
EndFunc

В итоге: стандартный UDF использует VBA-Find.Execute2007, который значительно меняет представление таблицы во время чтения - что приводит к тому что редактирование ее становится невозможным(т.к. информацию о таблице необходимо постоянно обновлять). К сожалению с VB я не особо дружу, чтобы попытаться что-то переделать...
 
Верх