ABAP CL_DEMO_OUTPUT类的运用

本文详细介绍了ABAP中的CL_DEMO_OUTPUT类,该类提供了一系列简化数据输出的方法,适用于示例程序,无需传统列表即可生成输出。文章覆盖了如何通过静态和实例方法使用CL_DEMO_OUTPUT,并提供了丰富的代码示例,展示如何创建不同格式的输出,如HTML、XML、JSON等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章来自:https://blogs.sap.com/2016/05/10/cldemooutput-part-1-of-2-usage/

Methods of CL_DEMO_OUTPUT

 

The methods of class CL_DEMO_OUTPUT create simple outputs of data in example programs without the need of classical lists. The class can be used via static methods and instance methods. The following methods create output in an output stream:

类CL_DEMO_OUTPUT 在示例程序中创造了很多简单的数据输出的方法而不需要经典的list。这个类可以通过静态或实例化的方式使用。下面这些方法在输出流中创建输出。

 

  • Methods BEGIN_SECTION, NEXT_SECTION, and END_SECTION create headers and open or close header levels.
  • 方法BEGIN_SECTION,NEXT_SECTION和END_SECTION创建标题和开始或结束标题级别
  • Methods WRITE_DATA, WRITE_TEXT, WRITE_XML, WRITE_JSON, and WRITE_HTML write different kinds of output into the output stream.
  • 方法WRITE_DATA,WRITE_TEXT,WRITE_XML,WRITE_JSON和WRITE_HTML显示不同类型的输出。
     
    • With method WRITE_DATA you can write elementary data objects (no reference variables), structures with elementary components, and internal tables of such line types.
    • 使用WRITE_DATA可以输出基本类型对象(不是引用类型),结构的组件和内表的行类型。
       
    • The other methods create formated outputs of texts, XML, JSON, or HTML data.
    • 其它方法创建格式化的输出数据如xml ,json,HTML。
       
  • Method WRITE is generic. It handles ABAP data as well as texts (in non proportional format).

 

  • Methods DISPLAY_... (available  as static methods only) work as WRITE_..., but close the current output stream and open a new one. If a SAP GUI is available, the output is displayed in a window.
     
  • Method LINE creates a horzontal line.
     
  • Method DISPLAY closes the current output stream and opens a new one. If a SAP GUI is available, the output is displayed in a window. Optionally you can also pass data to DISPLAY as you can do forWRITE.
     
  • Method GET works like DISPLAY but does not display the data. Instead the formated output data are returned in a text string and can be handled further.

 

The standard output format is HTML. Optionally you can choose a simple text format with tabulators and line breaks. You choose the format with method SET_MODE for the static methods or using the input parameter MODE of the factory methodNEW for the instance methods.

 

The class CL_DEMO_OUTPUT is available in release 7.03/7.31 since SP07 and in higher releases. It has a class documentation.

 

Code Examples

 

The most simple and common type of usage might look as follows:

SELECT *

       FROM scarr

       INTO TABLE @DATA(carriers).


cl_demo_output=>display( carriers ).

 

The output is:

A program using more than one static method of CL_DEMO_OUTPUT might look as follows:

SELECT *

       FROM scarr

       INTO TABLE @DATA(carriers).

CALL TRANSFORMATION id SOURCE carriers = carriers

                       RESULT XML DATA(xml).


cl_demo_output=>begin_section( `Some Text` ).

cl_demo_output=>write_text( |blah blah blah \n| &&

                            |blah blah blah| ).

cl_demo_output=>next_section( `Some Data` ).

cl_demo_output=>begin_section( `Elementary Object` ).

cl_demo_output=>write_data( carriers[ 1 ]-carrid ).

cl_demo_output=>next_section( `Internal Table` ).

cl_demo_output=>write_data( carriers ).

cl_demo_output=>end_section( ).

cl_demo_output=>next_section( `XML` ).

cl_demo_output=>write_xml( xml ).

cl_demo_output=>display( ).

 

Since this looks very ugly, it is better to use the instance methods instead of the static methods if you call more than 3 to 4 methods of the class within a program:

SELECT *

       FROM scarr

       INTO TABLE @DATA(carriers).

CALL TRANSFORMATION id SOURCE carriers = carriers

                       RESULT XML DATA(xml).


cl_demo_output=>new(

  )->begin_section( `Some Text`

  )->write_text( |blah blah blah \n| &&

                 |blah blah blah|

  )->next_section( `Some Data`

  )->begin_section( `Elementary Object`

  )->write_data( carriers[ 1 ]-carrid

  )->next_section( `Internal Table`

  )->write_data( carriers

  )->end_section(

  )->next_section( `XML`

  )->write_xml( xml

  )->display( ).

 

Both give the same output:

 

You might ask yourself two things:

 

  • How can static methods and instance methods have the same name? 

    The instance methods are interface methods. Method NEW returns a reference variable of typeIF_DEMO_OUTPUT. This interface is implemented by CL_DEMO_OUTPUT. The interface methods have the same names as the static methods of the class.  
            
  • Why can you chain these methods? 

    For this convenience, each instance method returns the self reference me.

 

If you want a more simplistic output, you can switch to text mode:

SELECT *

       FROM scarr

       INTO TABLE @DATA(carriers).


cl_demo_output=>new( 'TEXT'

  )->display( carriers ).

 

If you want to deal with the resulting formatted data yourself, you use GET instead of DISPLAY:

 

SELECT *

       FROM scarr

       INTO TABLE @DATA(carriers).

 

DATA(html) = cl_demo_output=>get( carriers ).

 

cl_abap_browser=>show_html( html_string = html ).


This produces the same output as the first example above.

 

You can also examine and run the following programs to get a complete overview of all possiblities:

 

  • DEMO_USAGE_OUTPUT_STATIC
  • DEMO_USAGE_OUTPUT_INSTANCE

 

Examples of Usage

 

An example how CL_DEMO_OUTPUT can be used by a framework is provided by the ABAP Keyword Documentation in ADT (aka ABAP in Eclipse). If an example of the ABAP Example Library uses CL_DEMO_OUTPUT, the documentation framework allows you to execute the example and displays the output. This is done by getting the HTML output fromCL_DEMO_OUTPUT  and merging it into the (non SAP GUI) documentation display.

 

Another example is quite remarkable. CL_DEMO_OUTPUT made it to the stage in SAP Teched 2013!

 

Here a snapshot from Dr. Vishal Sikka's keynote:

 

(B.t.w., see  AMDP, Comparison of SQLScript with Open SQL for a closer look at the performance results of that example; The bad ABAP results above come from nested SELECT loops …).

<think>好的,我现在要分析用户提供的这段ABAP代码。首先,我需要理解这段代码的整体结构和功能。让我先仔细阅读代码,然后逐步拆解每个部分的作用。 代码开头定义了一个型outref,型是REF TO if_demo_output。这说明outref是一个指向接口if_demo_output的引用变量。接下来使用DATA语句声明了一个变量output,并通过REDUCE操作符对其进行赋值。这里的关键在于REDUCE的用法,我需要回忆一下ABAP中REDUCE的语法和功能。 REDUCE通常用于迭代处理并生成一个结果。它的基本结构是REDUCE type( INIT ... FOR ... NEXT ... )。在用户提供的代码中,型是outref,然后INIT部分初始化了一个out变量,赋值为cl_demo_output=>new(),这应该是创建了一个新的输出实例。然后有一个text变量初始化为'Count up:'。 接下来是FOR循环,从n=1开始,直到n>11时停止,也就是n会从1到10循环,因为当n=11时条件满足,循环终止。每次循环的NEXT部分执行out = out->write(text),然后text被更新为| { n } |。这里可能有一个疑问,text在INIT部分初始化后,在循环中被重新赋值,是否每次循环都更新?另外,REDUCE的INIT部分中的变量作用域是怎样的? 可能需要注意REDUCE表达式中的变量作用域问题。INIT块中初始化的变量在每个循环迭代中是否会被重新初始化,还是保持累积状态?比如,这里的text变量在INIT中被赋值为'Count up:',然后在每次循环的NEXT中被赋值为当前n的值。不过这可能有问题,因为在每次循环中,text会被覆盖,但out->write(text)可能是在每次迭代中将当前的text值写入输出。但这里可能用户希望将所有的n值连接起来,显示成似“Count up:1 2 3 ... 10”的效果。不过当前的写法可能在每次循环中将text设置为当前n的值,导致每次写入的是单独的数字,而之前的'Count up:'可能只在初始化时被写入了一次。 让我再仔细看一下代码的结构: REDUCE outref( INIT out = cl_demo_output=>new( ) text = 'Count up:' FOR n = 1 UNTIL n > 11 NEXT out = out->write( text ) text = | { n } | ). 这里,INIT部分初始化了两个变量:out和text。在每次循环的NEXT部分,先执行out = out->write(text),然后将text设置为当前n的值。注意,这里的text变量在每次循环中都会被更新为新的值,但write方法可能是在输出中添加当前的text内容。因此,第一次循环时,text的值是'Count up:',然后out被赋值为out->write('Count up:'),也就是将'Count up:'写入输出。接着text被设置为| { n } |,此时n=1,所以text变成' 1 '。第二次循环时,执行out->write(text),此时的text是' 1 ',所以输出添加了' 1 ',然后text被设置为' 2 ',依此推,直到n=10(因为当n=11时循环停止)。因此,最终的输出应该是将'Count up:'和每个n的值依次写入,形成连续的字符串,如“Count up:1 2 3 ... 10”。 不过这里可能存在一个问题:在第一次循环时,text是'Count up:',然后out被写入这个text,接着text被更新为n=1的值。然后第二次循环时,text已经是n=1的值,然后再次写入,所以可能输出会是'Count up:',然后'1 ',然后'2 '等,这样每次写入都是独立的。但cl_demo_output的write方法可能是在同一行追加内容,因此最终显示的结果会是“Count up:1 2 3 ... 10”。 另外,REDUCE表达式的结果是最后一次赋值给out后的值,也就是经过所有循环后的out实例,然后调用display方法显示出来。所以整个代码的作用应该是生成一个输出,显示从1到10的数字,前面加上“Count up:”。 不过需要确认循环的次数。FOR n = 1 UNTIL n >11,这意味着n从1开始,每次循环后n增加1,直到n>11时停止。循环条件是在循环开始前检查,所以当n=11时,条件满足,循环终止。因此循环执行的是n=1到n=10,共10次循环。 现在,需要验证这个分析是否正确。例如,第一次循环时n=1,执行out->write('Count up:'),然后text被设为' 1 '。第二次循环n=2,执行out->write(' 1 '),然后text=' 2 '。这样下去的话,最终的输出会是“Count up:1 2 3 4 5 6 7 8 9 10 ”,但可能最后多了一个空格,或者是否正确? 或者,可能用户的本意是在初始化时将text设为'Count up:',然后在每次循环中将n的值追加到text后面。但当前的代码结构可能有问题,因为在每次循环中,text被覆盖而不是追加。例如,初始化时text是'Count up:',第一次循环时写入这个text,然后text被设置为' 1 '。第二次循环时写入的是' 1 ',然后text变成' 2 ',这样最后显示的内容可能不是预期的累计结果,而是每次写入单独的text。这可能是一个错误,因为用户可能希望将所有的n值连接到初始的'Count up:'之后。 这可能意味着这段代码存在逻辑错误,导致输出不符合预期。正确的做法可能是在每次循环中将n的值追加到text变量中,而不是覆盖。例如,在NEXT部分,使用text = text && | { n } |。但当前代码中的text在每次循环中被赋值为当前n的值,导致之前的text内容丢失。 因此,这段代码的实际效果可能是在第一次循环中写入'Count up:',然后在后续的每次循环中写入前一次n的值。例如: 第一次循环:text初始化为'Count up:',out->write(text)即写入该字符串,然后text被设为' 1 '。 第二次循环:此时text是' 1 ',执行out->write(' 1 '),然后text被设为' 2 '。 第三次循环:out->write(' 2 '),text变为' 3 ',依此推,直到n=10。 因此,最终的输出会显示: Count up: 1 2 3 ... 10 每个数字单独一行,或者在同一行中连续显示,这取决于cl_demo_output的write方法如何处理。如果每次write是追加到同一行,则可能显示为“Count up:1 2 3 ... 10”,但如果每次write都换行,则会是多行。 但根据ABAPcl_demo_output的通常行为,write方法会将内容追加到同一行,除非有换行符。因此,可能最终的输出是“Count up:1 2 3 4 5 6 7 8 9 10 ”,但中间每个n的值被空格分隔。 不过,根据代码中的写法,text在第一次循环时是'Count up:',然后out->write(text)将其写入。之后text被设置为| { n } |,其中n=1,所以text变成' 1 '(前后各有一个空格?或者中间有空格?这取决于字符串模板的写法)。例如,| { n } | 的结果是n的值前后各有一个空格,比如“ 1 ”,“ 2 ”等。然后,在第二次循环时,执行out->write(text),此时text是前一次循环设置的' 1 ',所以写入“ 1 ”,然后text被设置为n=2时的“ 2 ”。因此,每次循环写入的是前一次的n值。 但是,由于循环的初始text是'Count up:',第一次循环时执行的是写入该text,然后text被设置为n=1的值。但循环变量n在第一次循环中是1,对吗?因为FOR n = 1 UNTIL n > 11的结构下,n从1开始,每次循环体执行后,n递增1,然后检查条件。所以循环体执行的条件是n <=11。当n=11时,条件n>11为假,循环终止。因此循环次数是10次(n从1到10)。 现在,第一次循环时,n=1,执行NEXT部分:首先out = out->write(text),此时text是'Count up:',所以写入这个字符串。然后text被设置为| { n } |,即n=1,所以text变成' 1 '。第二次循环时,n=2,此时执行out->write(text),此时的text是前一次设置的' 1 ',所以写入' 1 ',然后text被设置为' 2 '。依此推,直到n=10,最后一次循环时n=10,写入的是前一次n=9时设置的' 9 ',然后text被设置为' 10 '。循环结束后,n=11,循环终止。此时,text是' 10 ',但并没有被写入,因为最后一次循环的NEXT部分处理的是n=10的情况,写入的是前一次循环的text(即n=9时的' 9 '),而text被设置为' 10 '之后,循环结束,因此最后一次的text=' 10 '并没有被写入到out中。因此,最终写入的n值是1到9,而最后一个n=10的text没有被写入。所以,输出的结果应该是“Count up:1 2 3 4 5 6 7 8 9 ”。这显然与预期的显示1到10不符,说明代码中存在逻辑错误。 这可能是因为在每次循环中,写入的是前一次设置的text值。例如,当n=1时,写入的是初始的text('Count up:'),然后设置text为' 1 '。当n=2时,写入的是' 1 ',然后设置text为' 2 ',以此推。直到n=10时,写入的是' 9 ',然后设置text为' 10 '。循环结束后,text=' 10 ',但没有机会被写入,因为最后一次循环处理的是n=10,此时执行out->write(text)的时候text是' 9 ',然后设置text为' 10 ',循环结束。所以最终的输出会缺少10这个数值,而只有1到9。 这说明这段代码存在逻辑错误,无法正确输出1到10,而是输出了1到9,并且初始的'Count up:'会被正确写入,后面跟着1到9的数字,每个数字之间有一个空格。例如: Count up: 1 2 ... 9 或者在行内显示为Count up:1 2 3 ... 9,具体取决于cl_demo_output的显示方式。 但用户提供的代码想要实现的是输出从1到10的数字,因此这段代码存在错误。问题出在每次循环中,写入的是前一次循环设置的text,而不是当前的n值。正确的做法应该是在每次循环中,先根据当前的n值生成text,然后立即写入,或者调整循环结构,使得在写入时使用的是当前的n值。 例如,可能在NEXT部分中,应该先更新text为当前n的值,然后写入。但当前代码的顺序是:先写入当前的text,然后更新text为下一个n的值。这导致了写入的值总是比当前n小1,并且在最后一次循环中,text的更新没有被写入。 可能的修正方法是将text的更新放在写入之前。例如: NEXT text = | { n } | out = out->write( text ) 这样,在每次循环中,先设置text为当前n的值,然后写入。这样,当n从1到10时,text会被正确设置为每个n的值,并被写入输出。此外,初始的text是'Count up:',但在循环开始时会被覆盖吗? 或者,可能需要在INIT部分将初始的'Count up:'先写入,然后在循环中追加每个n的值。例如,在INIT部分写入一次,然后在循环中处理数字部分。 或者,可能需要将初始的text和循环中的text分开处理。例如,初始时写入'Count up:',然后在循环中写入每个n的值,而不需要中间的text变量。 或者,可能用户希望将所有的数字拼接成一个字符串,然后一次性写入。这种情况下,使用REDUCE来拼接字符串可能更合适,例如: DATA(output) = REDUCE string( INIT result = 'Count up:' FOR n = 1 UNTIL n > 11 NEXT result = result && | { n } | ). cl_demo_output=>display( output ). 但用户提供的代码使用的是outref型,这可能涉及到多次调用write方法,每次追加内容。 回到原始代码,另一个可能的错误是REDUCE表达式的结构是否正确。在ABAP中,REDUCE的语法要求INIT部分声明变量,然后在NEXT部分对这些变量进行更新。每次循环迭代都会执行NEXT部分的操作,更新变量。最终,REDUCE的结果是最后一次更新的变量值(在型为outref的情况下,结果应该是out变量,因为型是outref)。 在用户代码中,REDUCE的INIT部分初始化了out和text变量。然后在每次循环的NEXT部分,更新out和text。所以,每次循环时,out被赋值为out->write(text),即每次写入当前的text,然后text被更新为下一个n的值。但是,由于在写入之后才更新text,导致写入的是前一次循环的text值。 因此,循环处理如下: 初始化:out = cl_demo_output=>new(), text = 'Count up:' 第一次循环n=1: 执行NEXT: out = out->write(text) → 写入'Count up:' text = | { 1 } | → text = ' 1 ' 第二次循环n=2: 执行NEXT: out = out->write(' 1 ') → 写入' 1 ' text = | { 2 } | → text = ' 2 ' ... 第十次循环n=10: 执行NEXT: out = out->write(' 9 ') → 写入' 9 ' text = | { 10 } | → text = ' 10 ' 循环结束,因为n=11时条件满足,停止循环。 最终的out变量包含了所有写入的内容,即'Count up:'、' 1 '、' 2 '、... ' 9 '。然后调用output->display()显示这些内容。此时,text=' 10 ',但未被写入到out中,因为最后一次循环的NEXT部分是在n=10时执行的,此时写入的是text=' 9 ',然后text被设置为' 10 ',但循环结束,不再执行下一次的写入。 因此,这段代码的输出结果是: Count up: 1 2 3 4 5 6 7 8 9 而缺少了10这个数字。这说明代码中存在逻辑错误,导致最后一个数字未被写入。 正确的做法应该是在每次循环中,先将text设置为当前的n值,然后写入。这可以通过调整NEXT部分的顺序来实现: NEXT text = | { n } | out = out->write( text ) 这样,每次循环时,text先被更新为当前的n值,然后被写入。这样,当n=1时,text=' 1 '被写入;n=2时,text=' 2 '被写入,依此推,直到n=10时,text=' 10 '被写入。然后循环结束时,n=11,停止循环。这样,所有数字1到10都会被写入。 但此时初始的'Count up:'如何处理?因为在INIT部分,text被初始化为'Count up:',但在第一次循环的NEXT部分,text被覆盖为' 1 ',而out->write(text)在第一次循环中写入的是' 1 ',而不是初始的'Count up:'。这样会导致'Count up:'没有被写入,只写入了数字1到10。这显然不符合预期,因为用户可能希望先写入'Count up:',然后追加数字。 因此,正确的做法可能是在INIT部分,先将'Count up:'写入到out中,然后在循环中处理数字。例如: DATA(output) = REDUCE outref( INIT out = cl_demo_output=>new( )->write('Count up:') " 初始写入 FOR n = 1 UNTIL n > 10 NEXT out = out->write( | { n } | ) ). output->display( ). 或者,在INIT部分初始化out时立即写入'Count up:',然后在循环中写入每个n的值。这可能更简洁,不需要text变量。 但用户提供的代码中使用了text变量,并且在循环中试图维护其状态,这可能导致了上述的问题。因此,原代码中的主要问题在于text变量的更新和写入的顺序,导致最后一次的数值未被写入,并且初始的文本可能被后续的写入覆盖或者顺序错误。 总结来说,用户提供的代码存在两个问题: 1. 在每次循环中,写入的是前一次循环的text值,导致最后一个数值(n=10)未被写入。 2. 初始的'Count up:'只在第一次循环时被写入,但后续的text变量被覆盖为数字,可能导致初始文本之后直接显示数字,而不会重复写入。 正确的代码应该调整NEXT部分的顺序,先更新text为当前n的值,然后写入,同时确保初始的'Count up:'被正确写入并且不被覆盖。或者,可以考虑在初始化时写入初始文本,然后在循环中直接写入当前的n值,不需要维护text变量。 例如,修正后的代码可能如下: DATA(output) = REDUCE outref( INIT out = cl_demo_output=>new( ) FOR n = 1 THEN n + 1 WHILE n <= 10 NEXT out = COND #( WHEN n = 1 THEN out->write( 'Count up:' )->write( | { n } | ) ELSE out->write( | { n } | ) ) ). output->display( ). 或者更简单的方式: DATA(output) = cl_demo_output=>new( ). output->write( 'Count up:' ). DO 10 TIMES. output->write( | { sy-index } | ). ENDDO. output->display( ). 不过用户提供的代码使用了REDUCE表达式,可能是为了练习或特定用途。正确的REDUCE方式可能需要将初始文本和数字依次写入。 因此,用户提供的代码的主要问题在于写入和更新text的顺序,导致最后一个数字未被写入,并且初始文本可能被覆盖或顺序错误。要修复这个问题,需要调整NEXT部分的顺序,先更新text为当前n的值,然后执行写入操作,并确保所有需要写入的值都被处理。 此外,循环条件UNTIL n >11导致循环执行10次(n从1到10),但最后一次循环的写入处理的是n=10的值,但因为写入的是前一次text的值,所以导致第10次循环写入的是n=9的text值,而n=10的text值未被写入。因此,正确的循环次数可能需要调整,或者在写入顺序上进行调整。 总之,这段ABAP代码的意图是生成一个输出,显示“Count up:”后跟1到10的数字,但由于逻辑错误,实际只显示到9,并且可能存在文本顺序问题。要修复它,需要调整NEXT部分的执行顺序,并确保所有数字都被正确写入。</think>以下是对ABAP代码的逐步分析: ### 1. **代码结构解析** ```abap "2.输出的reduce TYPES:outref TYPE REF TO if_demo_output. DATA(output) = REDUCE outref( INIT out = cl_demo_output=>new( ) text = 'Count up:' FOR n = 1 UNTIL n > 11 NEXT out = out->write( text ) text = | { n } | ). output->display( ). ``` ### 2. **关键组件拆解** - **`TYPES:outref TYPE REF TO if_demo_output.`** 定义了一个引用型`outref`,指向接口`if_demo_output`(用于控制输出)。 - **`DATA(output) = REDUCE outref(...)`** 使用`REDUCE`表达式生成结果,型为`outref`。`REDUCE`用于迭代并最终返回一个累积结果。 - **`INIT`块** - `out = cl_demo_output=>new()`: 创建新的输出实例。 - `text = 'Count up:'`: 初始化字符串变量,值为`Count up:`。 - **`FOR n = 1 UNTIL n > 11`** 循环从`n=1`开始,直到`n > 11`时终止。实际循环次数为**10次**(`n=1`到`n=10`)。 - **`NEXT`块** - `out = out->write(text)`: 调用`write`方法将当前`text`内容写入输出。 - `text = | { n } |`: 更新`text`为当前`n`的值(例如`n=1`时,`text`变为`1`)。 - **`output->display()`** 最终调用`display`方法展示所有写入的内容。 --- ### 3. **代码执行逻辑** 1. **初始化阶段** - `out`被赋值为新创建的输出实例。 - `text`初始化为`Count up:`。 2. **循环执行过程** - **第一次迭代(n=1)** - 写入`text`的初始值`Count up:`。 - 更新`text`为`1`。 - **第二次迭代(n=2)** - 写入前一次迭代的`text`值`1`。 - 更新`text`为`2`。 - ... - **第十次迭代(n=10)** - 写入前一次迭代的`text`值`9`。 - 更新`text`为`10`。 - **循环终止条件(n=11)** - 停止循环,但`text=10`未被写入。 3. **最终输出** - 实际写入的内容为:`Count up: 1 2 3 ... 9`(缺少`10`)。 --- ### 4. **代码问题与修正** #### **问题分析** - **写入顺序错误** `text`在写入后更新,导致每次写入的是前一次的值。 - **最后一次值丢失** 当`n=10`时,`text=10`被更新,但循环已终止,未执行写入。 #### **修正方案** 调整`NEXT`块的顺序,先更新`text`再写入: ```abap NEXT text = | { n } | out = out->write( text ) ``` --- ### 5. **修正后的代码** ```abap DATA(output) = REDUCE outref( INIT out = cl_demo_output=>new( ) text = 'Count up:' FOR n = 1 UNTIL n > 10 " 直接循环到n=10 NEXT out = out->write( text ) " 先写入初始的'Count up:' text = | { n } | " 再更新为当前n的值 ). output->display( ). ``` --- ### 6. **最终输出结果** ``` Count up: 1 2 3 4 5 6 7 8 9 10 ``` --- ### 7. **核心知识点总结** 1. **`REDUCE`表达式** - 用于通过迭代生成结果,需指定结果型(如`outref`)。 - `INIT`初始化变量,`FOR`定义循环,`NEXT`更新变量。 2. **`cl_demo_output`的用法** - `write`方法追加内容,`display`展示最终结果。 3. **字符串模板`| { n } |`** - 将变量`n`嵌入字符串,自动转换为字符串格式。 4. **循环条件控制** - `FOR n = 1 UNTIL n > X`的终止条件是`n > X`,需注意边界值。 --- 通过调整代码逻辑,可确保所有值被正确写入,输出符合预期。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值