Member Avatar for Member #773326

Hello,

I'm a Python/SPSS (DANIWEB) beginner and I'm having a hard time getting classes, functions and methods into the right order. I want to write a script for SPSS where I can read text out of an text object from the SPSS-output file. My code looks like this:

import SpssClient                                                 

SpssClient.StartClient()

OutputDoc = SpssClient.GetDesignatedOutputDoc()                     
OutputItems = OutputDoc.GetOutputItems()
OutputDoc.ClearSelection()


for index in range(OutputItems.Size()):
    OutputItems = OutputItems.GetItemAt(index)
    text = OutputItems.GetTextContents()
    if text.find("  Number of cases read:  0    Number of cases listed:  0") >= 0:
        OutputItems.SetSelected(True)

SpssClient.StopClient()       
print "fertig!"
OutputDoc.Delete()

error Message:
Traceback (most recent call last):
File "\\io\userdaten\EPIDEMIOLOGIE\Matthias\- Skripte\", line 11, in <module>
text = OutputItems.GetTextContents()
AttributeError: 'SpssClient.SpssOutputItem' object has no attribute 'GetTextContents'

I know that the I'm not using the "SpssOutputItem" Class inside my code. Why is it inside the error message?
The "GetTextContents" method is inside the "SpssLogItem" Class. How do I call these classes in the right way? I studied all the instructions but I can't get it right...
Could anyone help me please?

Dani AI

Generated

A compact clarification and practical pattern to complement the thread: the AttributeError happens because the object you get from OutputItems.GetItemAt(...) is the generic SpssOutputItem (the base viewer item). That base object does not implement text-reading methods. You must either check the item's type first or call GetSpecificType() to get the derived item (Log/Text/Title/Pivot types expose different APIs) before calling GetTextContents(). This behavior and the available output-type values are described in the SPSS Python reference. (scribd.com)

Small, robust pattern to follow (keeps the variable names distinct, checks type, and safely reads text):

for i in range(OutputItems.Size()):
    obj = OutputItems.GetItemAt(i)
    t = obj.GetType()
    # only attempt text for known text-bearing types
    if t in (SpssClient.OutputItemType.LOG,
             SpssClient.OutputItemType.TEXT,
             SpssClient.OutputItemType.TITLE):
        spec = obj.GetSpecificType()      # get the derived object
        try:
            text = spec.GetTextContents()
        except AttributeError:
            continue
        if "Number of cases read" in text:
            obj.SetSelected(True)

Notes, gotchas and quick troubleshooting (builds on and ):

  • Use GetType() or GetTypeString() to see exactly what each item is before calling item-specific methods; GetTypeString() returns human-readable names like "Log"/"Text"/"Table". (scribd.com)
  • Prefer the in operator for substring checks ("foo" in text) rather than testing .find() >= 0 (clearer and avoids off-by-one logic). Trim or lower-case the text if you need normalized comparisons.
  • Wrap calls in try/except so non-text items are skipped cleanly (Jon’s try/except pattern in the thread is a good idea). Call OutputDoc.Delete() (cleanup) before SpssClient.StopClient() to avoid leaving resources open.
  • For full API details and other output-item methods, consult the SPSS Python documentation (Python Scripting/Reference Guide) for your SPSS version. (ibm.com)

This adds a type-check + safe-call pattern to what and suggested, and should stop the AttributeError while keeping the code stable across different output-item kinds.

Recommended Answers

All 9 Replies

In this line
OutputItems = OutputItems.GetItemAt(index)
you are redefining OutputItems as a single output item, which, of course, then does not have a method GetItemAt.
Do it as
OutputItem = OutputItems.GetItemAt(index)
and then use GetTextContents on that.

HTH,
Jon Peck

Member Avatar for Member #773326

I see what you meant. I double called the methods. I corrected other mistakes in that category, but it is still not working.

import SpssClient                                                 

SpssClient.StartClient()

OutputDoc = SpssClient.GetDesignatedOutputDoc()                     
OutputItems = OutputDoc.GetOutputItems()

for index in range(OutputItems.Size()):
    OutputItem = OutputItems.GetItemAt(index)
    text = OutputItem.GetTextContents()
    if text.find("  Number of cases read:  0    Number of cases listed:  0") >= 0:
        OutputItem.SetSelected(True)

SpssClient.StopClient()       
print "fertig!"
OutputDoc.Delete()

Error Message:
..., line 10, in <module>
text = OutputItem.GetTextContents()
AttributeError: 'SpssClient.SpssOutputItem' object has no attribute 'GetTextContents'

I still know "GetTextContents" is inside the "SpssLogItem" Class and not in "SpssOutputItem". Why is it returning such an error?!

Use test printing, put before line 10 as test:

print OutputItem,type(OutputItem)

Not all output items have the GetTextContents method, e.g., header items, so you need either to check the type before calling the method or, better, just use a try/except block to catch and ignore the exception and proceed to the next item.

Member Avatar for Member #773326

Use test printing, put before line 10 as test:

print OutputItem,type(OutputItem)

Ok. I tested variable "OutputItem" by inserting "print". Before line 10 the output is:

<SpssClient.SpssOutputItem object at 0x01306360> <type 'SpssClient.SpssOutputItem'>

Traceback (most recent call last):
File "...", line 11, in <module>
text = OutputItem.GetTextContents()
AttributeError: 'SpssClient.SpssOutputItem' object has no attribute 'GetTextContents'

I guess this leads to this:

Not all output items have the GetTextContents method, e.g., header items, so you need either to check the type before calling the method or, better, just use a try/except block to catch and ignore the exception and proceed to the next item.

"OutputItem" takes the first item which is a LOG (SPSS Log containing the information of the SPSS-Syntax).
Then it tries to compare the LOG with the text "...Number of cases read...". This leads to an error.

Am I right?

Thanks for the help so far. At the moment I'm trying to set up a try/except block.

Two more problems:

First, before you can call GetTextContents, you have to call GetSpecificType. For example,
OutputItem = OutputItems.GetItemAt(index).GetSpecificType()

Another minor problem, you need to call the Delete method BEFORE calling StopClient.

HTH,
Jon Peck

Member Avatar for Member #773326

Two more problems:

First, before you can call GetTextContents, you have to call GetSpecificType. For example,
OutputItem = OutputItems.GetItemAt(index).GetSpecificType()

Another minor problem, you need to call the Delete method BEFORE calling StopClient.

HTH,
Jon Peck

I already fixed the "Delete" method in my version and all the other little things ;-)

At the start of this post I tried to call "GetSpecificType" but it led to:

AttributeError: 'SpssHeaderItem' object has no attribute 'GetTextContents'
I inserted it at the same place as you did.

OK. Here is an entire script (embedded as a program), that just prints whatever text it can find in the objects.

begin program.
import SpssClient
SpssClient.StartClient()
OutputDoc = SpssClient.GetDesignatedOutputDoc()
OutputItems = OutputDoc.GetOutputItems()
for index in range(OutputItems.Size()):
  try:
    OutputItem = OutputItems.GetItemAt(index).GetSpecificType()
    print index, OutputItem
    text = OutputItem.GetTextContents()
    print text
  except:
    pass
OutputDoc.Delete()
SpssClient.StopClient()
print "fertig!"
end program.
Member Avatar for Member #773326

Thanks for the code. This was my major problem. Now that I know the "text" variable is filled right, I just need to read out the content and compare it with my string.

Thanks so far! I will publish the code when it's done. And if I fail, I'll write again. ;-)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.