On-line: fokinal21, гостей 1. Всего: 2 [подробнее..]
АвторСообщение
администратор




Пост N: 2372
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 21.05.12 16:52. Заголовок: Снова EXCEL (продолжение)


Ранее с Excel из Harbour ни когда не работал.
Поставили тут задачу.
У некоторых поставщиков есть определенные формы заказов.
Набраны они в Excel. Сейчас народ руками заполняет эти формы
и шлет по электронке поставщикам.
Задача сводится к тому что бы в этих формах находить
нужные коды товара и в нужной ячейке проставлять заказ.
Может ткнет кто носом с чего начать что бы не напороться на грабли.
Спасибо
Сами формы тут http://zalil.ru/33279066

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 190 , стр: 1 2 3 4 5 6 7 8 9 10 All [только новые]


moderator


Пост N: 1087
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 15.04.17 22:35. Заголовок: fokinal21 пишет: А ..


fokinal21 пишет:

 цитата:
А как проверить?


Ну есть к примеру enumwindows которая возвращает список активных окон в системе.
Возможно есть способ проще, типа похендлу получить статус окна... именно живо ли оно


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 1441
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 15.04.17 23:47. Заголовок: Haz пишет: Возможн..


Haz пишет:

 цитата:
Возможно есть способ проще, типа похендлу получить статус окна


Валидность хэндла обычно проверяют с использованием WinAPI функции IsWindow()
В MiniGUI функция-враппер носит название IsWindowHandle().

if IsWindowHandle( oExcel:hWnd ) ...




Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 22
Зарегистрирован: 22.09.13
ссылка на сообщение  Отправлено: 16.04.17 11:19. Заголовок: oExcel ..


oExcel :=CreateObject( "Excel.Application" )
hWnd:=oExcel:hWnd

? hWnd
? IsWindowHandle(hWnd)

// Результаты: 462230 и .T.

oExcel:Quit()
? hWnd
? IsWindowHandle(hWnd)

// Результаты: 462230 и .T.

*По рекомендации Dima
oExcel:=nil


? hWnd
? IsWindowHandle(hWnd)

// Результаты: 462230 и .T.

// Итог: oExcel опять живее всех живых, несмотря на oExcel:Quit() и oExcel:=nil

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 6361
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 16.04.17 12:22. Заголовок: fokinal21 пишет: *П..


fokinal21 пишет:

 цитата:
*По рекомендации Dima
oExcel:=nil


? hWnd
? IsWindowHandle(hWnd)

// Результаты: 462230 и .T.

// Итог: oExcel опять живее всех живых, несмотря на oExcel:Quit() и oExcel:=nil



Ну тогда нужно так

oExcel:Quit()
oExcel:=nil


? hWnd:=oExcel:hWnd
? IsWindowHandle(hWnd)

// Итог: результат в студию


Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 523
Зарегистрирован: 08.07.06
ссылка на сообщение  Отправлено: 16.04.17 12:33. Заголовок: Dima пишет: oExcel:..


Dima пишет:

 цитата:
oExcel:Quit()
oExcel:=nil


? hWnd:=oExcel:hWnd
? IsWindowHandle(hWnd)

// Итог: результат в студию


Можно даже не компилировать - результатом будет ошибка времени исполнения, тк у переменной типа NIL не может быть свойства :hWnd

А ноги у этой проблемы вот отсюда растут: http://clipper.borda.ru/?1-4-0-00001096-000-0-0-1440920410
Вот тут тоже обсуждали: http://clipper.borda.ru/?1-4-0-00000591-000-0-0-1317808661

Вот решение: http://clipper.borda.ru/?1-4-0-00000876-000-0-0-1373554002

 func Start_Excel()  
Local Res:=.f.
#ifndef __XHARBOUR__
#xcommand TRY => BEGIN SEQUENCE WITH {|e| Break( e )}
#xcommand CATCH [<!oErr!>] => RECOVER [USING <oErr>] <-oErr->
#endif

TRY
oExcel := GetActiveObject( "Excel.Application" )
oExcel:DisplayAlerts:=.f.
Res:=.t.

CATCH
Res:=.f.
TRY
oExcel := CreateObject( "Excel.Application" )
Res:=.t.
CATCH
Res:=.f.
END
END
Return Res


Т.е. если процесс уже есть в памяти - использовать его, а не создавать новый.

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 23
Зарегистрирован: 22.09.13
ссылка на сообщение  Отправлено: 16.04.17 16:36. Заголовок: В общем понятно, что..


В общем понятно, что процесс Excel закрывается только после закрытия вызвавшей его программы, как ни крути Quit - ами и nil - ами. И это значит, что попытки выяснить с помощью хендла закрыл юзер окно с табличкой или нет обречены на провал, а это и надо было мне сделать. Может кто проведет другим путем?

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 6364
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 16.04.17 16:43. Заголовок: fokinal21 пишет: эт..


fokinal21 пишет:

 цитата:
это значит, что попытки выяснить с помощью хендла закрыл юзер окно с табличкой или нет обречены на провал


А зачем это контролировать ?
Выбросил форму в Excel а дальше юзер что хочет с ней то и делает.
У себя делаю примерно так:
oExcel:DisplayAlerts:=.t.
oExcel:Visible := .t.
oSheet:Cells( 1, 1 ):select()
//oSheet:Protect( "blabla" )
Showexcel(oExcel)


Спасибо: 0 
ПрофильЦитата Ответить
moderator


Пост N: 1088
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 16.04.17 18:42. Заголовок: fokinal21 пишет: Мо..


fokinal21 пишет:

 цитата:
Может кто проведет другим путем?


Да легко
Суть в том что любое окно порождено конкретным процессом. Отслеживать хендл окна дело бесперспективное т. к. Винда использует повторное пернназначение (хендл закрытого окна может пллучтьб вновь созданное)
Поэтому имеет смысл привязыватьсяименно к процессу еоторый это окно родил.
И задача сводится к тому что бы определить жив ли сам процесс.
Как определить? По алгоритму
1.зная окно можно найти процесс который его создал
2.зная процесс получить программу которая в нем выполняетя
3.и если это тот процесс и та программа то юзер ее еще не убил

Ps в харбуре есть инструмент чтоб этот алгоритм проверить
Будут вопросы пиши. На чтото я смогу ответить на что-то коллеги помогут


Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 24
Зарегистрирован: 22.09.13
ссылка на сообщение  Отправлено: 17.04.17 09:49. Заголовок: Haz пишет: Как опр..


Haz пишет:

 цитата:
Как определить? По алгоритму
1.зная окно можно найти процесс который его создал
2.зная процесс получить программу которая в нем выполняетя
3.и если это тот процесс и та программа то юзер ее еще не убил



Пока на все один большой вопрос ?
Чтобы превратить его в несколько маленьких ,стремящихся к 0, можно чуть подробнее и небольшой пример, можно ссылку, если таковой уже есть.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 1443
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 17.04.17 11:58. Заголовок: fokinal21 пишет: По..


fokinal21 пишет:

 цитата:
Пока на все один большой вопрос ?
Чтобы превратить его в несколько маленьких ,стремящихся к 0, можно чуть подробнее и небольшой пример, можно ссылку, если таковой уже есть.


Зачем это все прикладному программисту?

fokinal21 пишет:

 цитата:
В общем понятно, что процесс Excel закрывается только после закрытия вызвавшей его программы, как ни крути Quit - ами и nil - ами. И это значит, что попытки выяснить с помощью хендла закрыл юзер окно с табличкой или нет обречены на провал, а это и надо было мне сделать. Может кто проведет другим путем?


oExсel:hWnd хранит хэндл главного окна oExсel (с классом 'XLMAIN'), как вы его собираетесь использовать для определения окна с табличкой, это еще вопрос.
oExсel также имеет коллекцию Windows - "that represents all the windows in all the workbooks", вот я б с ней пробовал работать в вашей ситуации.




Спасибо: 0 
ПрофильЦитата Ответить
moderator


Пост N: 1089
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 18.04.17 11:13. Заголовок: fokinal21 пишет: По..


fokinal21 пишет:

 цитата:
Пока на все один большой вопрос ? Чтобы превратить его в несколько маленьких ,стремящихся к 0, можно чуть подробнее и небольшой пример, можно ссылку, если таковой уже есть.



Вот тот самый небольшой пример. Показывает окна их класс и заголовки. В том числе если есть открытая книга в Excel то ее и покажет в списке
 

#include "common.ch"
#include "i_winuser.ch"

#define WM_GETTEXT 0x000D
#define WM_SETTEXT 0x000C
#define WM_GETTEXTLENGTH 0x000E


Func main()
local hWnd := 0
local aWin := {}
local aChild := {}
local hChildWindow := 0
local i := 0
local j := 0
local nLen := 0
local nLenCh := 0


REQUEST HB_LANG_RU866
HB_LANGSELECT("RU866")

REQUEST HB_CODEPAGE_RU1251
hb_cdpSelect( "RU1251" )


aWin := EnumWindows()

nLen := len( aWin )


for i := 1 to nLen
aChild := EnumChild( aWin[ i ] )
nLenCh := LEN( aChild )
for j := 1 TO nLenCh
? aChild[j][2], aChild[ j ][3]
end
end
return NIL



Func EnumChild( hWin )
local aChild := {}
EnumChildWindows( hWin, { |hChild, nLParam | AADD( aChild, { hChild, GetClassName( hChild ), GetChildWindowText(hChild) } ) , .T. }, 0 )
return aChild


FUNCTION GetChildWindowText(hWnd )
LOCAL nLen, cText
nLen := SendMessage(hWnd, WM_GETTEXTLENGTH, 0, 0) + 1
cText := Space( nLen)
nLen := SendMessageString(hWnd, WM_GETTEXT, nLen, @cText)
RETURN substr(cText,1,nLen)



**********************************************************************************************************************************************
*
**********************************************************************************************************************************************

#pragma BEGINDUMP

#include <windows.h>

#include "hbapi.h"
#include "hbapiitm.h"

#include <hbapi.h>
#include <hbapiitm.h>
#include <windows.h>

void hb_evalBlock( PHB_ITEM pCodeBlock, ... );

static PHB_ITEM pCodeBlock = NULL;

BOOL CALLBACK static EnumChildProc( HWND hWnd, LPARAM lParam )
{
PHB_ITEM pHWnd = hb_itemPutNL( NULL, ( LONG ) hWnd );
PHB_ITEM pParam = hb_itemPutNL( NULL, ( LONG ) lParam );

if( pCodeBlock )
hb_evalBlock( pCodeBlock, pHWnd, pParam, 0 );

hb_itemRelease( pHWnd );
hb_itemRelease( pParam );

return hb_parl( -1 );
}

HB_FUNC( ENUMCHILDWINDOWS )
{
HWND hWnd = ( HWND ) hb_parnl( 1 );
LPARAM lParam = ( LPARAM ) hb_parnl( 3 );

pCodeBlock = hb_param( 2, HB_IT_BLOCK );
hb_retl( EnumChildWindows( hWnd, EnumChildProc, lParam ) );
pCodeBlock = NULL;
}


BOOL CALLBACK static EnumWinProc( HWND hWnd, LPARAM lParam )
{
PHB_ITEM pHWnd = hb_itemPutNL( NULL, ( LONG ) hWnd );
PHB_ITEM pParam = hb_itemPutNL( NULL, ( LONG ) lParam );

if( pCodeBlock )
hb_evalBlock( pCodeBlock, pHWnd, pParam, 0 );

hb_itemRelease( pHWnd );
hb_itemRelease( pParam );

return TRUE;
}



static PHB_ITEM pArray;

#if defined( __BORLANDC__ )
#pragma argsused
#endif

BOOL CALLBACK EnumWindowsProc( HWND hWnd, LPARAM lParam )
{
PHB_ITEM pHWnd = hb_itemPutNL( NULL, ( LONG ) hWnd );
#if defined( __MINGW32__ )
UNREFERENCED_PARAMETER( lParam );
#endif
hb_arrayAddForward( pArray, pHWnd );
hb_itemRelease( pHWnd );

return TRUE;
}

HB_FUNC ( ENUMWINDOWS )
{
pArray = hb_itemArrayNew( 0 );

EnumWindows( ( WNDENUMPROC ) EnumWindowsProc, ( LPARAM ) 0 );

hb_itemReturnRelease( pArray );
pArray = NULL;
}


BOOL CALLBACK EnumThreadWndProc( HWND hWnd, LPARAM lParam )
{
PHB_ITEM pHWnd = hb_itemPutNL( NULL, ( LONG ) hWnd );
#if defined( __MINGW32__ )
UNREFERENCED_PARAMETER( lParam );
#endif
hb_arrayAddForward( pArray, pHWnd );
hb_itemRelease( pHWnd );

return TRUE;
}


HB_FUNC ( GETCLASSNAME )
{
HWND hWnd = (HWND) hb_parnl( 1 );
TCHAR ClassName[ 1024 ];
GetClassName( hWnd, ClassName, sizeof (ClassName) / sizeof (TCHAR) );
hb_retc( ClassName );
}



HB_FUNC( GETWINDOWTEXT )
{
HWND hWnd = ( HWND ) hb_parnl( 1 );
int iLen = GetWindowTextLength( hWnd );
char * cText = ( char * ) hb_xgrab( iLen + 1 );
int iRet = GetWindowText( hWnd, ( LPSTR ) cText, iLen + 1 );

hb_retclen( cText, iRet );
hb_xfree( cText );
}


HB_FUNC( SENDMESSAGE )
{
hb_retnl( ( LONG ) SendMessage( ( HWND ) hb_parnl( 1 ), ( UINT ) hb_parni( 2 ), ( WPARAM ) hb_parnl( 3 ), ( LPARAM ) hb_parnl( 4 ) ) );
}

HB_FUNC( SENDMESSAGESTRING )
{
hb_retnl( ( LONG ) SendMessage( ( HWND ) hb_parnl( 1 ), ( UINT ) hb_parni( 2 ), ( WPARAM ) hb_parnl( 3 ), ( LPARAM ) ( LPSTR ) hb_parc( 4 ) ) );
}


HB_FUNC ( POSTMESSAGE )
{
hb_retl( (BOOL) PostMessage (
(HWND) hb_parnl (1),
(UINT) hb_parni (2),
(WPARAM) hb_parnl (3),
(LPARAM) hb_parnl (4) ) );
}


#pragma ENDDUMP






Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 25
Зарегистрирован: 22.09.13
ссылка на сообщение  Отправлено: 18.04.17 12:15. Заголовок: Всем спасибо за помо..


Всем спасибо за помощь и консультации!

Haz пишет:

 цитата:
Вот тот самый небольшой пример


Буду, по возможности, разбираться с примером...

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 6368
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 18.04.17 12:37. Заголовок: fokinal21 пишет: Бу..


fokinal21 пишет:

 цитата:
Буду, по возможности, разбираться с примером...


Пример по ходу отображается не верно , там где есть [ i ] только без пробелов внутри скобок

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 1410
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 18.04.17 12:42. Заголовок: Dima пишет Пример по..


Dima пишет
 цитата:
Пример по ходу отображается не верно


тут
 
for i := 1 to nLen
aChild := EnumChild( aWin[ i ] )
nLenCh := LEN( aChild )
for j := 1 TO nLenCh
? aChild[j][2], aChild[j][3]
end
end


Спасибо: 0 
ПрофильЦитата Ответить
moderator


Пост N: 1090
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 18.04.17 13:36. Заголовок: SergKis пишет: тут ..


SergKis пишет:

 цитата:
тут


Дима , Сергей , спасибо . Подправил [ и ]

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 1445
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 18.04.17 15:48. Заголовок: REQUEST HB_LANG_RU8..



 цитата:
 
REQUEST HB_LANG_RU866
REQUEST HB_CODEPAGE_RU1251

procedure Main( p, m )

local oExcel, oWorkBook, oWindows
local nI, nCount, w

hb_LangSelect( "RU866" )
hb_cdpSelect( "RU1251" )

hb_default( @p, "/" )
hb_default( @m, "/m" )

if hb_LeftEqI( p, "/g" ) .or. hb_LeftEqI( p, "-g" )
oExcel := win_oleGetActiveObject( "Excel.Application" )
elseif hb_LeftEqI( p, "/c" ) .or. hb_LeftEqI( p, "-c" )
oExcel := win_oleCreateObject( "Excel.Application" )
else
? Upper( __FILE__ ), '[/G|/C] [/M]'
? ' /C - Create new Excel object'
? ' /G - Get existing object'
? ' /M - Merge instances [by default]'
? ''
endif

if oExcel != NIL
IF hb_LeftEqI( m, "/m" ) .or. hb_LeftEqI( m, "-m" )
oExcel:MergeInstances := .T.
else
oExcel:MergeInstances := .F.
endif
? oExcel:hwnd
? '---------'
oWindows := oExcel:Windows()
oWorkBook := oExcel:WorkBooks:Add()

nCount := oWindows:Count
// Note that the active window is always Windows[1]
oWindows[1]:Caption := "xl#win#" + hb_NtoS( nCount )

for each w in oWindows
? w:caption
? w:hwnd
next

oExcel:Visible := .T.

//oExcel:Quit()
else
? "Error: MS Excel not available. [" + win_oleErrorText() + "]"
endif

return




Программа консольная.
Компилировать как-то так hbmk2 myexcel.prg -lhbwin

Запускать
myexcel /c /m
myexcel /g
myexcel /g
myexcel /g

Рекомендую посмотреть, проанализировать и сделать выводы

Интересно будет посмотреть на результат для разных версий Excel

P.S. Excel 2016 работает чудненько.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 6372
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 18.04.17 16:26. Заголовок: Петр пишет: P.S. Ex..


Петр пишет:

 цитата:
P.S. Excel 2016 работает чудненько.


На 2003 падает на oExcel:MergeInstances и закоментил пока , пересобрал , запустил с ключом /C и упал в цикле на ? w:hwnd


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 1447
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 18.04.17 16:38. Заголовок: Dima пишет: На 2003..


Dima пишет:

 цитата:
На 2003 падает на oExcel:MergeInstances


Настоящий Эксель начинается с 2013

Dima пишет:

 цитата:
упал в цикле на ? w:hwnd


Припоминаю, что где-то мы уже это обсуждали, у Ворда свойство hwnd есть, у Экселя нет. В 2007(?) вроде уже есть.


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 6374
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 18.04.17 21:21. Заголовок: Петр пишет: Настоящ..


Петр пишет:

 цитата:
Настоящий Эксель начинается с 2013


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

PS
У многих еще стоит XP и далеко не SP3 , так что заюзать могут офис только ниже 2010

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 1448
Зарегистрирован: 09.10.06
ссылка на сообщение  Отправлено: 18.04.17 22:12. Заголовок: Dima пишет: Кажется..


Dima пишет:

 цитата:
Кажется в примере не хватает проверки перед его запуском на версию офиса



Можно добавить в любом удобном месте
? oExcel:version

И танцевать от результата

Excel 2003 - 11.0
Excel 2007 - 12.0
Excel 2010 - 14.0
Excel 2013 - 15.0
Excel 2016 - 16.0


Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 190 , стр: 1 2 3 4 5 6 7 8 9 10 All [только новые]
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 250
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет