Sign in to follow this  
Followers 0
Omatsei

Control ID not right?

29 posts in this topic

I'm in the midst of writing a script that (I hope) will convert all the address book entries in Eudora to Outlook, and I've run into a bit of a snag. In Eudora, each entry has a "nickname" that serves as the primary identifier of that entry. I'm trying to retrieve the text typed in there, copy it into a variable, then use it later in the script. The problem is that the control ID doesn't appear to be correct. The Window Info tool tells me that the control ID is "2", but "2" returns nothing when I try to "ControlGetText" it (but other numbers, which are correct, do return values). Is there any other way to figure out which number to get it from, without resorting to messy alt-keys and clipboard copies?

Share this post


Link to post
Share on other sites



Little update...

Is it possible that a text field doesn't have a Control ID? I can find the ID for every other control field that I see, and some that I don't see, but this one is eluding me.

I just tried a sample little script, and at no point does it find the contents of the field I'm looking for... here's the code for that sample script.

$nickname = "testname"
$title = "Eudora"
for $i = 1 to 5000 step +1
    $dislistname = ControlGetText($title, "", $i)
    if $dislistname = $nickname Then
        msgbox(0, "Results", $i & " is set to: " & $dislistname)
    EndIf
Next

Am I missing something?

Share this post


Link to post
Share on other sites

Did you try using the AutoInfo.exe tool?

If there is no CotrolID is there a ClassNameNN?

Note: AutoIt only works with standard Microsoft controls - some applications write their own custom controls which may look like a standard MS control but may resist automation. Experiment!


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

Yes, the AutoInfo tool is what tells me that it should be Control ID 2, but that isn't it (that actually returns "Cancel"). The same tool also tells me the correct ID's of the other fields.

The classname is RichEdit20A46, and I've tried:

Opt("WinTitleMatchMode", 4)
$dislistname=ControlGetText("Eudora", "", "classname=RichEdit20A46")
msgbox(0, "whatever", "Name: " & $dislistname)

That still returns nothing. This is ... weird.

Share this post


Link to post
Share on other sites

I have a question about this.

Outlook has the ability to import mail and addresses from Eudora Pro and Light, versions 2.x through 4.x. Is this not an acceptable solution for you?

-S


(Yet Another) ExcelCOM UDF"A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly...[indent]...specialization is for insects." - R. A. Heinlein[/indent]

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

The short answer: no. It doesn't work with Eudora 6-7, which is what our users have.

The long answer: Eudora sucks, and doesn't have any export feature. You can only import things from Eudora into Outlook Express, then into Outlook, but the distribution lists are mangled in the process. Each address in the list is created as a separate contact, and if you have 200 names in each list, you end up with thousands of contacts (most of which are entered as "com, john.doe@company." because Outlook is retarded in the way it handles importing lists from other programs). The other option is to manually copy the addresses into an excel spreadsheet, then manually type in a name (or duplicate the email address) into a separate column, save it, then import that into Outlook. Either way, it's a mess. There's a couple programs out there that do this, but they charge $$, and some of the management types don't want to spend any money converting people away from Eudora (very long story). So I'm trying to write a script that'll do it for us.

Edited by Omatsei

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

$dislistname=ControlGetText("Eudora", "", "RichEdit20A46")oÝ÷ Øùn±«­¢+ØÌäí±Í͹µõ
±ÍÌÌäì

In the AutoInfo.exe you'll note right under the "Title" there is the "Class" of the interface. When using classname= you'll use that "Class" ... Not the ClassNameNN.

Edited by SmOke_N

[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

If you're familiar with Eudora at all, it's the field called "Nickname" at the top of the address book. The Control ID shows up as being "2", but it isn't. The ClassNameNN is "RichEdit20A46", and I can edit it, so it's not hidden or locked or anything weird... it's just, unaccessible through any automation means (from what I can tell).

Share this post


Link to post
Share on other sites

Well, that's a fine mess indeed.

The (not so) funny thing about it is this: I'm sure an hour of your time is worth more than $20.00.

Here's a tool that will do most of what you need (minus a step) for less than that:

ABC Amber Eudora Convert

So, how many hours do you estimate you will spend on this project? :whistle:

This is just an anecdote. I know you're committed to your project. I particularly like the "get it into Excel" idea, because if you can do that step, I can give you the tools & help to make short work of formatting it and importing it into Outlook.

-S


(Yet Another) ExcelCOM UDF"A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly...[indent]...specialization is for insects." - R. A. Heinlein[/indent]

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

It's not so much about the time, it's more of a learning experience for me also. I have lots of ideas and plans for how to use AutoIt, but unfortunately, my knowledge of it at the moment is rather wanting. One of my co-workers sees no purpose in AutoIt at all, and says he can do everything it can do in VB... except even if that is true, he never gets around to it. I don't know VB, and I'm more motivated to automate things that he is.

Anyhow, is there any way to set a variable to the text typed in a field with the focus that doesn't need the control ID? I can use hotkeys and such to get the focus onto that field, but now I just need to grab the text...

Edit: Oh, and it's only the address book I'm interested in. The ABC thing only converts the messages. Address Magic will do the address book, but I've not had good luck with it in the past (although that was with version 1.5, not 3.0, which is the current).

Edited by Omatsei

Share this post


Link to post
Share on other sites

It's not so much about the time, it's more of a learning experience for me also. I have lots of ideas and plans for how to use AutoIt, but unfortunately, my knowledge of it at the moment is rather wanting. One of my co-workers sees no purpose in AutoIt at all, and says he can do everything it can do in VB... except even if that is true, he never gets around to it. I don't know VB, and I'm more motivated to automate things that he is.

Anyhow, is there any way to set a variable to the text typed in a field with the focus that doesn't need the control ID? I can use hotkeys and such to get the focus onto that field, but now I just need to grab the text...

Edit: Oh, and it's only the address book I'm interested in. The ABC thing only converts the messages. Address Magic will do the address book, but I've not had good luck with it in the past (although that was with version 1.5, not 3.0, which is the current).

1. Did you read my Edit?

2. Did you try the example I gave?

3. Did you read the quote from the help file that I posted?


[center]Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.[/center]

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

It's not so much about the time, it's more of a learning experience for me also. I have lots of ideas and plans for how to use AutoIt, but unfortunately, my knowledge of it at the moment is rather wanting. One of my co-workers sees no purpose in AutoIt at all, and says he can do everything it can do in VB... except even if that is true, he never gets around to it. I don't know VB, and I'm more motivated to automate things that he is.

Anyhow, is there any way to set a variable to the text typed in a field with the focus that doesn't need the control ID? I can use hotkeys and such to get the focus onto that field, but now I just need to grab the text...

Edit: Oh, and it's only the address book I'm interested in. The ABC thing only converts the messages. Address Magic will do the address book, but I've not had good luck with it in the past (although that was with version 1.5, not 3.0, which is the current).

Sorry, I sent you the link to the wrong ABC Amber program. The address converter is a little more expensive.

As to your question, simulate a double or triple click. That should highlight the text in the field. You can then send CTRL-C to grab said text. Then use ClipGet() to put it into a string variable.

As an aside, is there any chance you can attach a sample nndbase.* file? I mean one that you create real quick that doesn't have sensitive data in it. It's the file that holds Eudora addresses. I'd like to have a look at one, if you don't mind. It might be easier to convert the addresses by parsing this file...

-S

Edited by Locodarwin

(Yet Another) ExcelCOM UDF"A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly...[indent]...specialization is for insects." - R. A. Heinlein[/indent]

Share this post


Link to post
Share on other sites

Sorry, I sent you the link to the wrong ABC Amber program. The address converter is a little more expensive.

As to your question, simulate a double or triple click. That should highlight the text in the field. You can then send CTRL-C to grab said text. Then use ClipGet() to put it into a string variable.

As an aside, is there any chance you can attach a sample nndbase.* file? I mean one that you create real quick that doesn't have sensitive data in it. It's the file that holds Eudora addresses. I'd like to have a look at one, if you don't mind. It might be easier to convert the addresses by parsing this file...

-S

In Eudora 6 & 7, the file in question should be called "NNDBASE.NNT" and, surprise, it is actually a text file. That makes it a total cakewalk to parse through.

Here's a forum thread about this situation:

Eudora Thread

Yup, the latest version of Eudora holds nickname files in NNDBASE.NNT instead of older NNDBASE.TXT. Hence, Netscape, Thunderbird, Dawn utility, and I couldn't read the NNT Eudora file. So I simply copied NNDBASE.NNT to a clone NNDBASE.TXT, left it in the Eudora subdirectory, and it imported nicely into Netscape 7.2 and Thunderbird. Thanks!

If the file is really a text file, then I strongly urge you to take the file-parse approach.

The reason why I am trying to gently steer you away from keystrokes and clicks is because it almost never works perfectly. Sometimes you'll get a nice run, sometimes you won't. Sometimes things will popup or close out or fall apart and leave you stranded. It's just a mess. Take it from a guy who has spent well over a year trying to automate Windows applications in this manner - it's like Eudora. It sucks.

-S


(Yet Another) ExcelCOM UDF"A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly...[indent]...specialization is for insects." - R. A. Heinlein[/indent]

Share this post


Link to post
Share on other sites

Yes, I tried the Class... as much as I could. The class never changes as long as you're within the Eudora window. It always says "EudoraMainWindow".

I'm taking Locodarwin's advice and trying to parse the nndbase directly, but it's not very easy. I have a feeling this is going to be a lot of if...endif's and for...next's....

Share this post


Link to post
Share on other sites

Yes, I tried the Class... as much as I could. The class never changes as long as you're within the Eudora window. It always says "EudoraMainWindow".

I'm taking Locodarwin's advice and trying to parse the nndbase directly, but it's not very easy. I have a feeling this is going to be a lot of if...endif's and for...next's....

No worries - I've got a sample nndbase.* and I'll have some prelim code shortly.

File format, for those interested:

Eudora Address File Format

It's not quite as simple as it looks, though. While the space character is a delimeter between fields, it is also legal inside of fields - so a straight-up chop-separation of the fields cannot be done reliably with just a StringSplit(). Nor will an Excel import work correctly (which was my first hope). There's a bit of algorithmin' to be done.

-S


(Yet Another) ExcelCOM UDF"A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly...[indent]...specialization is for insects." - R. A. Heinlein[/indent]

Share this post


Link to post
Share on other sites

Okay, this should be enough to get you started. The following code will parse your nndbase.* file and place the contents into arrays. Each array will contain one field of the contacts information:

$aType[] will contain the type of each contact entry (either an alias, or a note)

$aName[] will contain the name of the contact

$aTheRest[] will contain either email addresses (in the case of aliases) or additional fields and email addresses.

It's up to you where to go from there; I've made some recommendations in the code.

; Parse the names in a Eudora address file

#include <Array.au3>

; Create our item array - we'll make it an arbitrary size that we know we'll never breach
Global $aFile[5000], $iCount = 0

; Create handle to the file
$hFile = FileOpen("C:\NNDBASE.TXT", 0)      ; or whatever it is on your system

; Items are separated by carriage returns, so read the file into an array by lines
; What we'll be left with is an array of items with element[0] equal to the number of items
While 1
    $iCount = $iCount + 1
    Local $tLine = FileReadLine($hFile)
    If @error = -1 Then ExitLoop
    $aFile[$iCount] = $tLine
Wend
$aFile[0] = $iCount

; We know now how many items we have - let's Dim our field arrays accordingly
Global $aType[$iCount], $aName[$iCount], $aEmail[$iCount], $aTheRest[$iCount]  ; etc.

; Now we need to take each item and split it up into fields

; First of all, we know the first Eudora field is either "alias" or "note" and ends with a space...
; So let's get that field into an array called "Type" and shave it off the main item array
For $xx = 1 To $iCount - 1
    $aTemp = StringSplit($aFile[$xx], " ")
    If @Error Then
        MsgBox(1, "Big Problem...", "Line " & $xx & " isn't formatted correctly!")
        Exit
    EndIf
    $aType[$xx] = $aTemp[1]
    If $aTemp[1] = "alias" Then
        $aFile[$xx] = StringRight($aFile[$xx], StringLen($aFile[$xx]) - 6)
    Else
        $aFile[$xx] = StringRight($aFile[$xx], StringLen($aFile[$xx]) - 5)
    EndIf
Next

; Now let's extract the names.  Note that some of them are enclosed in quotes; the ones that are have spaces in the name,
; so we can't just do a split based on the space in that case.  We have to test for those quotes.
For $xx = 1 To $iCount - 1
    If StringLeft($aFile[$xx], 1) = '"' Then
        $aTemp = StringSplit($aFile[$xx], '"')
        If @Error Then
            MsgBox(1, "Big Problem...", "Line " & $xx & " isn't formatted correctly!")
            Exit
        EndIf
        $aName[$xx] = $aTemp[2]
        $aFile[$xx] = StringRight($aFile[$xx], StringLen($aFile[$xx]) - (StringLen($aTemp[2]) + 2))
    Else
        $aTemp = StringSplit($aFile[$xx], " ")
        If @Error Then
            MsgBox(1, "Big Problem...", "Line " & $xx & " isn't formatted correctly!")
            Exit
        EndIf
        $aName[$xx] = $aTemp[1]
        $aFile[$xx] = StringRight($aFile[$xx], StringLen($aFile[$xx]) - StringLen($aTemp[1]))
    EndIf
Next

; Now we put the rest of the main array into another array we'll call "TheRest"
Global $aTheRest = $aFile

;-------------------------
; "TheRest" is up to you!
;-------------------------

; The array "TheRest" will contain all of the email addresses, in the case of aliases.  When preparing for your import, you can
; tell whether a contact is a distro list by checking to see how many email addresses that contact's array element has.  Just
; one email means it's a standard contact.  Best approach: do a StringSplit() with the comma as the delimiter.

; In the case of notes, "TheRest" will contain parameters enclosed in <> characters, with each piece of data separated from
; the parameter by a colon.  That should be pretty easy to parse and place into other arrays.

-S


(Yet Another) ExcelCOM UDF"A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly...[indent]...specialization is for insects." - R. A. Heinlein[/indent]

Share this post


Link to post
Share on other sites

I think I've got it... and I've started integrating some of the COM calls instead of using mouse clicks (boy is that faster!), but I'm having some trouble creating a distribution list instead of a contact. I don't know anything at all about COM commands, so what I have is pretty limited...

$objOutlook = ObjCreate( "Outlook.Application" )
$objContact = $objOutlook.CreateItem( 2 )
$objContact.FullName = $name
$objContact.Email1Address = $distlist[1]
$objContact.Save

That works fine for creating a contact, but not so well with a distribution list (which basically is only any line that start with "alias" and has more than 1 e-mail address). Given that I don't know anything about what I'm doing, and that the information online seems to only be relevant to VB and such, is there a simple way to tell it to create a distribution list, then add email addresses? Given my limited understanding, and the info I've found online, I would have thought it'd be something like:

$objOutlook = ObjCreate( "Outlook.Application" )
$objOutlookNamespace = $objOutlook.GetNamespace("MAPI")
$objDistList = $objOutlook.CreateItem("olDistributionListItem")
$objDistList.Name = $name
; Starting at 3 because 1 is "alias" and 2 is the name
for $z = 3 to $distlist[0]
    $objDistList.AddNewMember = $distlist[$z]
next
$objDistList.Save

However, that doesn't seem to work... it keeps crapping out at "olDistributionList" as if it's waiting for something after the close parentheses.

Share this post


Link to post
Share on other sites

I think I've got it... and I've started integrating some of the COM calls instead of using mouse clicks (boy is that faster!), but I'm having some trouble creating a distribution list instead of a contact. I don't know anything at all about COM commands, so what I have is pretty limited...

$objOutlook = ObjCreate( "Outlook.Application" )
$objContact = $objOutlook.CreateItem( 2 )
$objContact.FullName = $name
$objContact.Email1Address = $distlist[1]
$objContact.Save

That works fine for creating a contact, but not so well with a distribution list (which basically is only any line that start with "alias" and has more than 1 e-mail address). Given that I don't know anything about what I'm doing, and that the information online seems to only be relevant to VB and such, is there a simple way to tell it to create a distribution list, then add email addresses? Given my limited understanding, and the info I've found online, I would have thought it'd be something like:

$objOutlook = ObjCreate( "Outlook.Application" )
$objOutlookNamespace = $objOutlook.GetNamespace("MAPI")
$objDistList = $objOutlook.CreateItem("olDistributionListItem")
$objDistList.Name = $name
; Starting at 3 because 1 is "alias" and 2 is the name
for $z = 3 to $distlist[0]
    $objDistList.AddNewMember = $distlist[$z]
next
$objDistList.Save

However, that doesn't seem to work... it keeps crapping out at "olDistributionList" as if it's waiting for something after the close parentheses.

The reason it dies there is because .CreateItem() requires an integer, like in the call you made in your first code snippet.

Office uses constants for many of its method parameters. You can tell a constant easily by the fact that it starts with at least 2 small letters representing the application. For you, that's "ol," for Outlook. Excel uses "xl" and Word uses "wd," and so on.

So the trick is to find the value of that constant.

Here's a nice little list of common Outlook constants:

Outlook Constants

According to this list, olDistributionListItem = 7.

So change your code to this:

$objOutlook = ObjCreate( "Outlook.Application" )
$objOutlookNamespace = $objOutlook.GetNamespace("MAPI")
$objDistList = $objOutlook.CreateItem(7)
$objDistList.Name = $name
; Starting at 3 because 1 is "alias" and 2 is the name
for $z = 3 to $distlist[0]
    $objDistList.AddNewMember = $distlist[$z]
next
$objDistList.Save

...and you should see success.

-S


(Yet Another) ExcelCOM UDF"A human being should be able to change a diaper, plan an invasion, butcher a hog, conn a ship, design a building, write a sonnet, balance accounts, build a wall, set a bone, comfort the dying, take orders, give orders, cooperate, act alone, solve equations, analyze a new problem, pitch manure, program a computer, cook a tasty meal, fight efficiently, die gallantly...[indent]...specialization is for insects." - R. A. Heinlein[/indent]

Share this post


Link to post
Share on other sites

I'm really starting to feel like a pest, but I'm still having problems with the distribution lists being created. My final question: Apparently the ".AddNewMember" part doesn't work... I figured out that it had to be "DLName" instead of ".Name", but I can't figure out how to tell it to add a member to the list (and the distribution list isn't getting created, but I think that's because there aren't any members).

Share this post


Link to post
Share on other sites

Minor update... I still can't get it to create new members in the list, but if I remove the lines telling to create a new member, it does create the list, so that's good. The only part that's missing now is the "add new member" section. I've tried dozens of permutations of VB / VBScript code that I've found, but nothing's worked so far. Then again, I know almost nothing about VB / VBScript, and I certainly don't know enough to combine the VB code with the AutoIt code.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0