2008年02月24日

      最近对一个透明表做了些修改,由于开发机上该表已有不少记录不能激活,就想直接做一个透明表的维护视图,在网上找了些资料,只有文字又写得不够详细(这些人提供的资料也太令人汗颜了,应该只有做过的人才看得懂),我弄一个早上,试了很久才把它搞定:
1、创建好透明表(如透明表名为ZRPG);
2、生成维护对象:
(1)运行事务代码se54,输入透明表名ZRPG,选择生成方式“生成对象”,点【创建/修改】进入下一屏幕;如下图:
 

(注:也可从se11的“表格生成器”(功能与se54同)进入下面的屏幕)
(2)在本屏幕中,输入“权限组”(一般可为&NC&)、“函数组”(即透明表名)、“屏幕号”(可自己定义),如下图:

(3)保存。
3、给维护视图建立事务代码:
(1)运行事务代码se93,tcode类型选择为:“Transaction with parameters(parameter transaction)”,事务代码为:zrpg;
(2)在“事务”输入“SM30”;选中“跳过启始屏幕”;选中“Inherit GUI attribute”;输入默认字段:VIEWNAME = ‘ZRPG’和UPDATE = ‘X’;如下图:

(3)保存激活即可。
4、运行事务代码zrpg即可看到效果。

转自 http://tb.blog.csdn.net/TrackBack.aspx?PostId=1889640

2008年01月27日

(转自)http://zhouwubin.blogbus.com/logs/14351256.html

刚开始学ABAP的时候,学到iternal table时,感觉一阵混乱.
搞不清楚什么是work area,什么是header line,以及occurs是干什么用的.
今天终于差不多搞明白了(我还是太弱啊…BS自己一下)
所以还是记录下来..省得自己以后再忘记…

先是用TYPES关键字定义一个行(row)的类型.如下:
TYPES: BEGIN OF line,
  field1 TYPE i,
  field2 TYPE i,

END OF line.

这里的line,就相当于一个自定义的类型,表示一行(row)的字段(field).
这里一行有两个字段field1和field2.

然后是声明一个work area:
DATA wa TYPE line.
我用C++(还是对cpp最有好感^^)的概念理解就是,
line是一个class,而wa是一个object.

接着是声明一个每一行的类型是line的internal table:
DATA itab TYPE line OCCURS 0.
我在暂时把OCCURS作为了区别工作区和内表的标志.
OCCURS应该有更深层次的意义,但我目前只能领悟至此…
当我们用以上这个方法来声明一个iternal table时,可以选择是否有无header line.
上面这句就是没有header line的.改成如下就有了:
DATA itab TYPE line OCCURS 0 WITH HEADER LINE.
有无header line的区别就是,header line可以当作一个work area来使用(参照我之前的一个日志).
有一下两种方式操作itab:
1).
wa-field1 = 1.
wa-field2 = 2.
APPEND wa TO itab.

2).
itab-field1 = 1.
itab-field2 = 2.
APPEND itab.

这里wa就是上面那个已经定义的work area.
有header line的时候,这两种都可以.
无header line的时候,只能用第1种.
第2种里,itab的意义是一个header line,而不是内表.
因为"DATA itab TYPE line OCCURS 0 WITH HEADER LINE."这样的声明,
已经隐式声明了一个与内表同名的header line.
所以OCCURS用来声明内表可能造成二义性(ambiguous).
于是,OCCURS被认为是old的东西,采用一下方式声明一个内表比较好:
DATA itab TYPE STANDARD TABLE OF line.

还有一种声明内表的方法:
DATA: BEGIN OF itab OCCURS 0,
              field1 TYPE i,
              field2 TYPE i,
           END OF itab.

这样的itab就自动有了一个同名的header line.
好像不会有 WITHOUT HEADER LINE 或者 NOT WITH HEADER LINE 这样的用法…
如果没有OCCURS 0,比如这样:
DATA: BEGIN OF itab,
              field1 TYPE i,
              field2 TYPE i,
          END OF itab.

那么这个itab就不是内表咯,只是一个structure,可以作为itab的work area.

写到这里发现,归根到底就是TYPES和DATA这两个关键字的区别嘛.
还有有无OCCURS的区别.

这样一想,简单明了~~

2006年01月02日


class CAsyncSocketExHelperWindow;
class CAsyncSocketExLayer;
class CCriticalSectionWrapper;

class CAsyncSocketEx : public CObject
{
 DECLARE_DYNAMIC(CAsyncSocketEx)
public:

 //Attaches a new layer to the socket.
 BOOL AddLayer(CAsyncSocketExLayer *pLayer);


 //Trigers an event on the socket
 // Any combination of FD_READ, FD_WRITE, FD_CLOSE, FD_ACCEPT, FD_CONNECT and FD_FORCEREAD is valid for lEvent.
 BOOL TriggerEvent(long lEvent);

protected:
 //Strucure to hold the socket data
 struct t_AsyncSocketExData
 {
  SOCKET hSocket; //Socket handle
  int nSocketIndex; //Index of socket, required by CAsyncSocketExHelperWindow
 } m_SocketData;

 //If using layers, only the events specified with m_lEvent will send to the event handlers.
 long m_lEvent;

 //Critical section for thread synchronization
 static CCriticalSectionWrapper m_sGlobalCriticalSection;

 //Pointer to the data of the local thread
 struct t_AsyncSocketExThreadData
 {
  CAsyncSocketExHelperWindow *m_pHelperWindow;
  int nInstanceCount;
  DWORD nThreadId;
 } *m_pLocalAsyncSocketExThreadData;

 //List of the data structures for all threads
 static struct t_AsyncSocketExThreadDataList
 {
  t_AsyncSocketExThreadDataList *pNext;
  t_AsyncSocketExThreadData *pThreadData;
 } *m_spAsyncSocketExThreadDataList;

 //Initializes Thread data and helper window, fills m_pLocalAsyncSocketExThreadData
 BOOL InitAsyncSocketExInstance();

 //Layer chain
 CAsyncSocketExLayer *m_pFirstLayer;
 CAsyncSocketExLayer *m_pLastLayer;

 friend CAsyncSocketExLayer;

 //Called by the layers to notify application of some events
 virtual int OnLayerCallback(const CAsyncSocketExLayer *pLayer, int nType, int nParam1, int nParam2);

 friend CAsyncSocketExHelperWindow;
};

. Network Implementation Analysis

    FileZilla的网络部分的结构图如下:

其中CAsyncSocketEx是对MFC的CAsyncSocket的改进,据说比CAysncSocket性能上要高一点。在CAsyncSocketEx中添加了对CAsyncSocketLayer的支持,各个SocketLayer 链接成一个双向的链表(见CAsyncSocketExLayer::m_pNextLayer和CAsyncSocketExLayer::m_pPrevLayer),在CAsyncSocketEx中记录了这个链表的头尾指针。
    对FileZilla来说网络就是其核心,而FillaZilla的网络部分主要就是CAsyncSocketEx和CAsyncSocketExLayer了,下面我们来分析一下CAsyncSocketEx和CAsyncSocketExLayer的工作机制。
    首先讲讲CAsyncSocketEx,其实在MFC里面有一个对基于HWND的异步事件的Winsock管理模型的封装类CAsyncSocket,但作者Tim Kosse这里又重新了一个CAsyncSocketEx类提供了跟MFC的CAsyncSocket相同的接口方法和功能,在eMule开源项目中我发现其网络部分也是用的这个FileZilla中的CAsyncSocketEx。那么CAsyncSocketEx比CAsyncSocket好,好在哪里呢?Tim Kosse在解释为什么CAsyncSocketEx比MFC的CAsyncSocket快时说:"每个使用CAsyncSocket的线程都会创建一个window,CAsyncSocket就是使用这个窗口的句柄来调用WSAAsyncSelect的,直到这里CAsyncSocketEx和CAsyncSocket都是一样的,但是对一个线程中的所有Socket,CAsyncSocket仅仅使用一个消息WM_SOCKET_NOTIFY,其wParam是套接字的句柄,而window通过一个内部建立好的map,根据这个套接字的句柄来获取CAsyncSocket的Instance.而CAsyncSocketEx就不同了,它使用了从WM_USER到0xBFFF的消息来为每个Socket提供一个通知消息,这样window在接受到一个消息后,将 index of message – WM_USER作为内部数组的Index来获取CAsyncSocketEx的Instance.所以CAsyncSocketEx就要比CAsyncSocket快一些,特别是在管理大量的Socket的时候,性能的提升还是比较明显的。".另外,CAsyncSocketEx还提供了a flexible layer system和套接字的状态机实现。

    接下来我们来分析一下CAsyncSocketEx的Layer系统是如何工作的.
    
从上图我们可以看到,CAsyncSocketEx将Receive,Send,Close,Connect,Create,Listen,Accept,ShutDown,GetPeerName,GetSockName这些调用按照左边的顺序一层一层的往下抛,一直到最后一个Layer才真正调用相应的API函数。同时,Helper窗口函数在收到通过WSAASyncSelect机制发过来的事件时,首先将其发给最下面一层处理,然后按照上图右边的顺序,从下往上通过OnReceive,OnClose,OnAccept,OnConnect,OnSend 一层一层的调用。
    同时,CAysncSocketLayer还使用WM_USER消息将其内部错误反馈给CAsyncSocketEx(通过TriggerEvent,PostMessage到HelperWindow);在CAysncSocketLayer和CAsyncSocketEx之间还有一个Callback机制,CAsyncSocketExLayer::DoLayerCallback把消息封装成t_callbackMsg,调用CAsyncSocketEx::AddCallbackNotification添加到CAsyncSocketEx的内部队列m_pendingCallbacks中等待处理。
    我感觉对CAsyncSocketLayer的机制还不是很清晰,下面再进一步分析一个Layer的实现吧.在FileZilla中已经实现了三个Layer了:ProxyLayer,sFtp Layer和SSL Layer.下面找个最简单的分析一下啦,就看Proxy Layer吧:) CAsyncProxySocketLayer主要是提供了对SOCKSv4,SOCKSv5和HTTP1.1 代理的支持。通过其源代码的分析,其也主要是在Connect和GetHostByName这两个部分做了一些处理,使得在连接应用服务器之前先连接上代理服务器,并对客户端进行认证,在代理服务器上建立circuits .其他的就没什么了。在 CAsyncSocketLayer的实现中,可以看到其主要还是利用SendNext,ReceiveNext,XXXXNext方法来处理数据,而不是在末尾调用CAsyncSocketLayer基类的同样方法。在发现错误的时候通过调用TriggerEvent和DoLayerCallback来向上层报告相关的网络错误。