Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Attachmate - Read Cursor Location 3

Status
Not open for further replies.

Christadelphian

Technical User
Feb 17, 2008
14
GB
Hello All,

Can anyone help please? Can anyone tell me whether its possible to find the current Cursor Location on an EXTRA screen, without using the co-ordinates in the bottom-left hand corner of the screen?

I am wanting to search extra for a specific reference (an order ID). Should the reference be found, there may be a corresponding reference found on the same line (an associated order). I then want to open the associated order, and read its status.

An associated order will always be found on the same line as the order reference I am looking for. However the Order reference may not always be located in the same place on the EXTRA screen.
I am unable to use Sendstring to tab through to the associated order (this I have tried, but my Macro often returns incorrect values due to the way orders are displayed on the screen).
If I can get my macro to read the row value co-ordinate of the order ID, I can then have the macro validate whether there is an associated order on the same line.

I hope this makes sense to everyone?

Any help would be greatly appreciated...... Thanks in advance.

Chris

Stats are like a drunk with a lampost used more for support than illumination!
 
I have posted my code in case it helps..... its not very sophisticated! Please note, its written in Excel VB.

Private Sub CommandButton1_Click()
'Declare Variables
Dim CSSRef As String
Dim PageValidationString As String
Dim CSSID As String
Dim Database As String
Dim ApptDate As String
Dim CRDate As String
Dim OrderStatus As String
Dim CP As String
Dim OrderType As String
Dim AssocOrderStatus As String
Dim HalfOrder As String

Dim StartTime As Date
Dim FinishTime As Date

Dim RowCount As Integer
Dim ColNumber As Integer
Dim RowNumber As Integer
Dim QuickWin As Integer

'Set Session Values
Set oXL = Excel.Application
Set oWB = oXL.ActiveWorkbook
'Set oSheet = oWB.ActiveSheet

Set System = New ExtraSystem
Set Sessions = System.Sessions
Set Sess0 = System.ActiveSession
Set MyScn = Sess0.Screen

TodaysDate = Date

StartTime = Time()

Worksheets("Sheet1").Activate

Set oSheet = oWB.ActiveSheet

'Initialise CSS Application
Set System = CreateObject("EXTRA.System") ' Gets the system object

If (System Is Nothing) Then MsgBox "Could not create the EXTRA System object. Stopping macro playback.: Stop"
Set Sessions = System.Sessions
If (Sessions Is Nothing) Then: MsgBox "Could not create the Sessions collection object. Stopping macro playback.: Stop"
Set Sess0 = System.ActiveSession
If (Sess0 Is Nothing) Then MsgBox "Could not create the Session object. Stopping macro playback. : Stop"

'--------------------------------------------------------------------------------
' Set the default wait timeout value
g_HostSettleTime = 30 ' milliseconds

OldSystemTimeout& = System.TimeoutValue
If (g_HostSettleTime > OldSystemTimeout) Then
System.TimeoutValue = g_HostSettleTime
End If

' Get the necessary Session Object
Set Sess0 = System.ActiveSession
If (Sess0 Is Nothing) Then
MsgBox "Could not create the Session object. Stopping macro playback."
Stop
End If

If Not Sess0.Visible Then Sess0.Visible = True
Sess0.Screen.WaitHostQuiet (g_HostSettleTime)


'---------------------------------------------------------------------------------

RowCount = ActiveSheet.UsedRange.Rows.Count ' Find Current Number Of Utilised Rows

MsgBox (RowCount) ' Utilised Row Validation

QuickWin = 0

'Populate Column Headings
oSheet.Cells(1, 8).Value = "Order Status"
oSheet.Cells(1, 9).Value = "Order Type"
oSheet.Cells(1, 10).Value = "Associated Order Status"

For x = 2 To RowCount ' For Every Row, find Order Status & Type
'y = x + 1
CSSRef = oSheet.Cells(x, 4).Value
Sendstring ("<Reset><Home>DO<Tab>" & CSSRef)
Sess0.Screen.WaitHostQuiet (g_HostSettleTime)
HalfOrder = Getstring(1, 9, 6)
Sess0.Screen.WaitHostQuiet (g_HostSettleTime)
Sendstring ("<Enter>")
Sess0.Screen.WaitHostQuiet (g_HostSettleTime)
OrderStatus = Getstring(10, 72, 4)
oSheet.Cells(x, 8).Value = OrderStatus
Sess0.Screen.WaitHostQuiet (g_HostSettleTime)
OrderType = Getstring(3, 73, 7)
Sess0.Screen.WaitHostQuiet (g_HostSettleTime)
oSheet.Cells(x, 9).Value = OrderType

'If order is STOP, tab to associated order to find status
If OrderType = "STOP " Then
Sendstring ("<Reset><Home>DIO")
Sess0.Screen.WaitHostQuiet (g_HostSettleTime)
Sendstring ("<Enter>")
Sess0.Screen.WaitHostQuiet (g_HostSettleTime)
'Set MyArea = MyScreen.Search(HalfOrder)
Sendstring ("<Tab>Y")
Sess0.Screen.WaitHostQuiet (g_HostSettleTime)
Sendstring ("<Enter>")
Sess0.Screen.WaitHostQuiet (g_HostSettleTime)
AssocOrderStatus = Getstring(10, 72, 4)
oSheet.Cells(x, 10).Value = AssocOrderStatus
End If

'If order is CLOSED, CANCELLED or CAUSED ERROR - add to Quickwins
If OrderStatus = "WCAN" Then
QuickWin = QuickWin + 1
oSheet.Rows(x).Select
Application.CutCopyMode = False
With Selection.Interior
.ColorIndex = 3
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
End With

ElseIf OrderStatus = "CLSD" Then
QuickWin = QuickWin + 1
oSheet.Rows(x).Select
Application.CutCopyMode = False
With Selection.Interior
.ColorIndex = 3
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
End With

ElseIf OrderStatus = "EONC" Then
QuickWin = QuickWin + 1
oSheet.Rows(x).Select
Application.CutCopyMode = False
With Selection.Interior
.ColorIndex = 3
.Pattern = xlSolid
.PatternColorIndex = xlAutomatic
End With
End If

If OrderType = "PROVIDE" Then
Provisions = Provisions + 1
End If

Next

' Summarise findings (End Of Spreadsheet)
x = RowCount + 1
oSheet.Cells(x, 4).Value = "Quickwins ="
oSheet.Cells(x, 5).Value = QuickWin
x = RowCount + 1
oSheet.Cells(x, 4).Value = "Quickwins ="
oSheet.Cells(x, 5).Value = QuickWin

FinishTime = Time()

MsgBox ("Data has been populated. The operation started at " & StartTime & " and completed at " & FinishTime & ".")

Set Sessions = Nothing
Set System = Nothing
Set Sess0 = Nothing
Set MyScn = Nothing
Set oXL = Nothing
Set oWB = Nothing
Set oSheet = Nothing


End Sub

Stats are like a drunk with a lampost used more for support than illumination!
 

Hi,
However the Order reference may not always be located in the same place on the EXTRA screen.
Is there absolutely no logic to where the OrderReference is placed on the screen? I find that hard to believe.

It may be that ScreenA has the OrderReference in one location, ScreenB has it in another and ScreenC has it in yet a third location, for instance.


Skip,
[sub]
[glasses]Just traded in my old subtlety...
for a NUANCE![tongue][/sub]
 


BTW, you have lots of Attachmate statements that have no screen object. Example...
Code:
...
        Sendstring ("<Reset><Home>DO<Tab>" & CSSRef)
        Sess0.Screen.WaitHostQuiet (g_HostSettleTime)
        HalfOrder = Getstring(1, 9, 6)
...
Should be...
Code:
...
        [b]Sess0.Screen.[/b]Sendstring ("<Reset><Home>DO<Tab>" & CSSRef)
        Sess0.Screen.WaitHostQuiet (g_HostSettleTime)
        HalfOrder = [b]Sess0.Screen.[/b]Getstring(1, 9, 6)
...


Skip,
[sub]
[glasses]Just traded in my old subtlety...
for a NUANCE![tongue][/sub]
 
Hi Skip,

Thanks for your help!
The orders are displayed with some form of logic on the screen. They are next to each other in a sequential order or found on the line above a previous order. Those with an associated order are always found on the same line as the order with which they are associated.
My problem stems from the fact that I am attempting to read the status of an order, and its associate.
Using the sendstring("<Tab">) function I have written, often means that EXTRA will tab to another order (which is closed or unrelated, and read the status of that associated order).
I have included an example of how they appear on the page below:

{ } MQW973 10/06/09 STP ENGS 25/06/09 { } MQW944
{ } KSM682 24/03/09 STA CLSD 08/04/09 { } KSM680

The STP Order (MQW973, is associated with MQW944, and KSM682 is associated with KSM680 etc....

Should MQW973 not have a related order however, EXTRA will <Tab> to KSM682, and incorrectly report the status of the Associated order as CLSD or Closed. It was for this reason I was hoping to find a method of reading the screen location automatically to validate the fact that, the next order was found on the same line, and was therefore an associated order.

The HalfOrder reference was my attempt at locating the Associated Order using a screen search (this failed miserably as I'm not sure I understand the Search and MoveTo syntax sufficiently, so I removed the code). Sendstring and Getstring are Private Functions, which are called. I can include my code in its entirety if you prefer, although there isn't much more to it?

I appreciate you taking the time to help.

Stats are like a drunk with a lampost used more for support than illumination!
 



GetString is an Attachmate function. SendString is not. I would NOT call your Private function GetString! Very confusing and not an accepted practice.

I have never used code the navigate a screen. I often grab the entire screen and process that string (in the case of an IMS screen 24 lines * 80 columns is 1920 bytes) using a loop.

I also define the fields on the screen in a table...
[tt]
ScrName FldName FrRow ToRow Col Len Type
[/tt]
where
[tt]
ScrName screen name
FldName field name
FrRow from row
ToRow to row (where a field is repeated in a column)
Col start column
Len field length
Type Character or Numeric
[/tt]
If I know what row & column I'm on in my loop, I know what the field is.

If I know what the field is, I know where it is on the screen.

using this technique, you can know EXACTLY what is on the screen without tabbing.

Alternatively, you could write a function using the WaitForCursor function and loop thru every postion on the screen until you get to where the cursor is, and return that data.

Skip,
[sub]
[glasses]Just traded in my old subtlety...
for a NUANCE![tongue][/sub]
 
Ok Skip,

I'll give the string processing a try, although not amazingly confident about my abilities to do so. It had never occured to me to do it this way, although it seems logical.

The Getstring and Sendstring functions were simply to make my life a bit easier as I have them stored along with a list of global variables in an excel module.....for example:

Global Const CssF20 = "<pf20>"
Global Const CssF21 = "<pf21>"
Global Const CssF23 = "<pf23>"
Global Const CssF24 = "<pf24>"
Global Const CssEnter = "<enter>"
Global Const CssTab = "<tab>"
Global Const CssDown = "<down>"
Global Const CssReset = "<reset>"
Global Const CssHome = "<home>"

But if this is not advisable, I will knock it on the head.

Thanks for all your help.

Regards

Stats are like a drunk with a lampost used more for support than illumination!
 
If I can get my macro to read the row value co-ordinate of the order ID, I can then have the macro validate whether there is an associated order on the same line.

Code:
row = sess0.screen.row
col = sess0.screen.col

btw, what is the significance of these brackets { }
({ } MQW973 10/06/09 STP ENGS 25/06/09 { } MQW944)

it would seem easier to look for the brackets instead of tabbing

hth
 
Hi Vzachin,

Thanks for that. I wasn't aware I could read the row and column in such a way. Much Appreciated!

The brackets are where Attachmate will allow for user entry. Placing a 'Y' in between the {} and pressing Enter, allows the user to select that record and bring up the relevant details.

I've managed to process an entire screen as a string (as Skip suggested) so I may use the brackets as an indicator, as you have suggested. It was a lot of work to begin with, but now its written I'm on to a winner!

Thanks to both of you.

Stats are like a drunk with a lampost used more for support than illumination!
 
Skip, could you elaborate on your post of 17 Aug 09 11:44 ?

1) Do you mean you store your field information in an Excel table?
2) How do you go about using the information in the table when you're looking for something in the screen string?

I'm working on a macro where I'm going to be scraping amounts from 40 or 50 different fields. The fields will always start at the same columns, but can appear on different rows. I'm wondering if your method might work for me.

Thanks,

-LB
 
I agree with Skip, if you are using Excel or Access at all with your Extra Script, write everything in VBA within Excel or Access.

You open extra, send a few keystrokes, scrape data from the screens (sometimes lots of data from several screens), then loop over a Field Definitions table/sheet/list and convert that data depending on date/currency/etc, write that data into excel, close extra)

Though it's designed for Access the following VBA code could easily be ported to Excel. It hides most of the hard work in a class/module and should give you some ideas.

Development and Debugging in VBA (Access or Excel) is FAR nicer than in Attachmate Extra .. and you have decent library functions ;)

Though the name escapes me there is a nice tool that plugs into VBA 2003 that does auto-indentation and javadoc type stuff to make it very nice.
 
why wouldnt you just try something like

Code:
variable = Sess0.Screen.Area.(1, 20, 1, 25).Value
this will get the value of the text at the specified region, in this case, row 1, column 20 to row 2, column 25. So you get six characters back and assign them to 'variable' which you should have
Code:
Dim variable As String
you can then perform a logical operation with this variable
Code:
if variable = "this" then 
     doThis()
else
     doThat()
end if
also, if you need to move the cursor to a certain area of the screen before performing an action or a key press, it is a lot easier to use the moveTo command
Code:
'Sets the cursor to a specific screen location
'in this case, row 10, column 14 on the screen
Sess0.Screen.MoveTo(10, 14)
also, the following code can be run in VBA for excel to assist in screen mapping.
The min (top left) of my window is 1,1 and the max (bottom right) is 24,80. You should be able to identify these values and adjust them to the size of your window
(please note that while this idea might have been thought of elsewhere, my intent was to create an original program. no one is to take the code and claim it as their own but may edit and modify it as they wish)

I have found it best to go in to the worksheet after it runs and highlight all the columns by their alpha indicator in excel for the horizontal range of your session screen, in my case columns 1, 80 (idk their alpha indicators off the top of my head) and change the column width to 1.14

i know there is a way to code that in but this was meant to be a quick and easy sub that can map a screen to excel to help you identify fields and values by their screen coordinates
Code:
Sub ScreenRip()
 
    Dim System, Sess0, excel_app As Object
    ' Get the main system object
        Set System = CreateObject("EXTRA.System")   
            If (System Is Nothing) Then
                MsgBox "Could not create the EXTRA System object.  Stopping macro playback."
                Stop
            End If
        Set Sessions = System.Sessions
 
        If (Sessions Is Nothing) Then
            MsgBox "Could not create the Sessions collection object.  Stopping macro playback."
            Stop
        End If
    
        'Set the time for the host screen to settle
        g_HostSettleTime = 250
      
        If (g_HostSettleTime > System.TimeoutValue) Then
            System.TimeoutValue = g_HostSettleTime
        End If
 
        Set Sess0 = System.ActiveSession
        
        If (Sess0 Is Nothing) Then
            MsgBox "Could not create the Session object.  Stopping macro playback."
            Stop
        End If
        If Not Sess0.Visible Then Sess0.Visible = True
        Sess0.Screen.WaitHostQuiet (g_HostSettleTime)
        
        Dim rCount, cCount As Integer
        Dim ExcelSource, toExcel As String
        
        'Can be modified to target any file
        ExcelSource = "c:\excel\ScreenRun.xls"
        
        Set excel_app = CreateObject("Excel.Application")
        excel_app.Workbooks.Open (ExcelSource)
        Set excel_sheet = ActiveSheet
        
        rCount = 1
        
        Do While rCount <= 24
            cCount = 1
    
            Do While cCount <= 80
                toExcel = ""
                toExcel = Sess0.Screen.Area(rCount, cCount, rCount, cCount).Value
                excel_sheet.Cells(rCount, cCount).Value = toExcel
                cCount = cCount + 1
            Loop
                
            rCount = rCount + 1
        
        Loop
               
        MsgBox ("Screen rip complete.  Please change the target file 'ScreenRun' to get the capture to a new tab and formatted properly")
               
End Sub

enjoy! :)
-obfuscate




 
Hi Christa, you may have already solved this problem already, however I thought this may help you in the future, having read some of the comments I know its not easy to understand how CSS works and displays information..
this is how I get around the problem being a CSS usre my self....... its not the best script in the world however it may help you understand how to manipulate, your script



LastExcelRow = Excel_Sheet.Cells(Cells.Rows.Count, 1).End(xlUp).Offset(1).Row
For Excel_Row = InputBox("Input Starting Row") To LastExcelRow

SPOKScreen_Obj.SendKeys ("<Reset><Home><EraseEOF>")
SPOKScreen_Obj.SendKeys ("dcs")
SPOKScreen_Obj.MoveTo 1, 9
SPOKScreen_Obj.PutString Excel_Sheet.Cells(Excel_Row, 1).value
SPOKScreen_Obj.SendKeys ("<enter>")
SPOKScreen_Obj.WaitHostQuiet (g_HostSettleTime)
SPOKScreen_Obj.SendKeys ("dio<Enter>")
SPOKScreen_Obj.WaitHostQuiet (g_HostSettleTime)

i = 9

Do
result = Trim(SPOKScreen_Obj.GetString(i, 26, 4))
result1 = Trim(SPOKScreen_Obj.GetString(i, 8, 6))
sDB = Trim(SPOKScreen_Obj.GetString(24, 79, 2))
sJobNum = result1 & sDB
If result = ("CHA") Then
If Excel_Sheet.Cells(Excel_Row, 1).value <> sJobNum Then
SPOKScreen_Obj.MoveTo i, 4
SPOKScreen_Obj.SendKeys ("y<Enter>")
SPOKScreen_Obj.WaitHostQuiet (g_HostSettleTime)

' Check for "Request Completed" (for multiple pages) outputting each page to file First page
Set SearchComplete = SPOKScreen_Obj.Search("REQUEST COMPLETED")
If SearchComplete = "" Then
Set MyArea = SPOKScreen_Obj.Area(24, 2, 24, 11, , 10)
Else
Set MyArea = SPOKScreen_Obj.Area(24, 2, SearchComplete.Bottom, 10)
End If

' While loop for subsequent pages
While SearchComplete = ""
Set SearchComplete = SPOKScreen_Obj.Search("CONVERSION FROM SINGLE LINE TO EMBARK")
If SearchComplete = "" Then
Set SearchComplete = SPOKScreen_Obj.Search("PROVIDE 1 EMBARK CAL CONV-EXLINE")
If SearchComplete = "" Then
Set SearchComplete = SPOKScreen_Obj.Search("CONVERSION FROM HUNT LINE TO EMBARK")
If SearchComplete = "" Then
Set SearchComplete = SPOKScreen_Obj.Search("THIS IS A SINGLE LINE EMBARK CONVERSION ORDER")
If SearchComplete = "" Then
Set SearchComplete = SPOKScreen_Obj.Search("THIS IS A MULTILINE EMBARK CONVERSION ORDER")
If SearchComplete = "" Then
Set SearchComplete = SPOKScreen_Obj.Search(" ")
If SearchComplete = "" Then
End If
End If
End If
End If
End If
End If
Wend

sPcode = SearchComplete
If (sPcode = "CONVERSION FROM SINGLE LINE TO EMBARK") Or (sPcode = "PROVIDE 1 EMBARK CAL CONV-EXLINE") _
Or (sPcode = "CONVERSION FROM HUNT LINE TO EMBARK") Or (sPcode = "THIS IS A SINGLE LINE EMBARK CONVERSION ORDER") _
Or (sPcode = "THIS IS A MULTILINE EMBARK CONVERSION ORDER") Then
Excel_Sheet.Cells(Excel_Row, 2).value = sPcode
result = Trim(SPOKScreen_Obj.GetString(12, 44, 9))
SPOKScreen_Obj.WaitHostQuiet (g_HostSettleTime)
Excel_Sheet.Cells(Excel_Row, 3).value = result
SPOKScreen_Obj.WaitHostQuiet (g_HostSettleTime)
GoTo done
Else
SPOKScreen_Obj.SendKeys ("dio<Enter>")
SPOKScreen_Obj.WaitHostQuiet (g_HostSettleTime)
End If
End If
End If
i = i + 1
Loop Until (i = 21) Or (Len(result) <= 0)
done:
SPOKScreen_Obj.WaitHostQuiet (g_HostSettleTime)
ActiveWindow.SmallScroll Down:=1


Next Excel_Row

End Sub


 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top