楼主: ganghz

[转载] Oracle Form 6i开发

[复制链接]
论坛徽章:
259
地主长老
日期:2008-05-16 13:45:41春季摄影比赛纪念奖
日期:2008-06-04 10:35:252008欧洲杯之星
日期:2008-07-01 14:52:28金牌徽章
日期:2008-09-04 11:32:50地主之星
日期:2009-03-30 10:29:22欧洲冠军杯纪念徽章
日期:2009-05-31 09:59:59NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA之星
日期:2010-04-15 14:14:34NBA大富翁
日期:2010-04-15 14:17:22博彩之星
日期:2010-07-12 13:14:39
21#
 楼主| 发表于 2008-8-24 15:16 | 只看该作者
1. 打开windows
一般情况下 会在form-level的pre-form trigger中调用app_window.set_window_position函数来指定the first window.
FND_STANDARD.FORM_INFO('$Revision: 115.12 $', 'Demo Order Form', 'DEMVCEOR', '$Date: 2006/07/18 17:12  $', '$Author: appldemvc $');
app_standard.event('PRE-FORM');
app_window.set_window_position('ORDERS', 'FIRST_WINDOW');
其它情况下,如使用键盘切换当前Block或用button打开窗体时,需使用APP_CUSTOM.OPEN_WINDOW函数,APP_CUSTOM.OPEN_WINDOW 中又会调用app_window.set_window_position。如果是Master-Detail Block需要建立coordination关系的,在APP_CUSTOM.OPEN_WINDOW('LINES')时,调用APP_WINDOW.SET_COORDINATION('OPEN-WINDOW', :CONTROL.ORDERS_LINES, 'ORDERS_LINES');
PROCEDURE LINES(EVENT VARCHAR2) IS
BEGIN
  IF (EVENT IN ('WHEN-BUTTON-PRESSED', 'KEY-NXTBLK'))
    THEN APP_CUSTOM.OPEN_WINDOW('LINES');
  ELSE
    FND_MESSAGE.DEBUG('Invalid event passed to orders.lines: '|| EVENT);
  END IF;
END LINES;
可在Block-level的KEY-NXTBLK trigger 或 Block-level的when-button-pressed trigger中调用这些PROCEDURE;需要注意的是这些代码请先在app_custom包中改写,对应包中的注释,可以很好理解OPEN_WINDOW的逻辑。
总结一下打开windows的逻辑:1设置windows位置;2 重置master-detail 关系(如有需要的话);3导航到window中的一个block。

使用道具 举报

回复
论坛徽章:
259
地主长老
日期:2008-05-16 13:45:41春季摄影比赛纪念奖
日期:2008-06-04 10:35:252008欧洲杯之星
日期:2008-07-01 14:52:28金牌徽章
日期:2008-09-04 11:32:50地主之星
日期:2009-03-30 10:29:22欧洲冠军杯纪念徽章
日期:2009-05-31 09:59:59NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA之星
日期:2010-04-15 14:14:34NBA大富翁
日期:2010-04-15 14:17:22博彩之星
日期:2010-07-12 13:14:39
22#
 楼主| 发表于 2008-8-24 15:16 | 只看该作者
2. 关闭windows
关闭windows的逻辑可参看app_custom.close_window函数及其注释,不难发现步骤1是判断该窗体是否处于query-mode,是的话不允许关闭;2判断该window是否为the first window,是的话调用app_window.close_first_window函数;3假如window是Detail window的话,延迟其与Master window的同步同步关系(APP_WINDOW.SET_COORDINATION)并GO_BLOCK(' previous-block ')。最后是Hide_Window。
此处我有个疑问:Oracle文档一直提是延迟(defer)而不是重设coordination,难道close windows时会自动使coordination check box变成‘DEFERRED’,一直不解。另外Hide_Window是不是也仅使window不可见,而不是使其在内存中卸载。

使用道具 举报

回复
论坛徽章:
259
地主长老
日期:2008-05-16 13:45:41春季摄影比赛纪念奖
日期:2008-06-04 10:35:252008欧洲杯之星
日期:2008-07-01 14:52:28金牌徽章
日期:2008-09-04 11:32:50地主之星
日期:2009-03-30 10:29:22欧洲冠军杯纪念徽章
日期:2009-05-31 09:59:59NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA之星
日期:2010-04-15 14:14:34NBA大富翁
日期:2010-04-15 14:17:22博彩之星
日期:2010-07-12 13:14:39
23#
 楼主| 发表于 2008-8-24 15:16 | 只看该作者
3. 控制master-detail windows
master-detail windows的行为控制需通过coordination check box来表现,coordination check box创建在Control block下,Property Class –> CHECKBOX_COORDINATION。coordination check box选中与否决定其取值是‘IMMEDIATE’ 还是‘DEFERRED’。如果coordination check box选中的话,即使焦点在Master window时,Detail window中数据会于Master window同步;如果coordination check box没有选中,Detail window的内容不会于Master window同步,直到焦点落在Detail window时,系统才会执行查询更新数据。这个过程自己试验一下会非常的清楚。使用coordination check box 必须在其WHEN-CHECKBOX-CHANGED trigger中重置Master-Detail windows的同步关系。
Eg:
PROCEDURE orders_lines(EVENT VARCHAR2) IS
  BEGIN
    IF (EVENT = 'WHEN-CHECKBOX-CHANGED') THEN
      APP_WINDOW.SET_COORDINATION (EVENT, :CONTROL.ORDERS_LINES, 'ORDERS_LINES');
    ELSE
      FND_MESSAGE.DEBUG('Invalid event passed to control.order_lines '|| EVENT);
    END IF;
END orders_lines;

4. Set Context-Dependent Window Title
     动态设置相关联的窗体标题依靠APP_WINDOW.SET_TITLE函数,注意在两类trigger中需要调用它。一类是Block-level的pre-record和on-insert trigger,另一类是相关联字段的when-validate-item trigger,我一直没搞清楚pre-record trigger为什么要调用APP_WINDOW.SET_TITLE函数。

使用道具 举报

回复
论坛徽章:
259
地主长老
日期:2008-05-16 13:45:41春季摄影比赛纪念奖
日期:2008-06-04 10:35:252008欧洲杯之星
日期:2008-07-01 14:52:28金牌徽章
日期:2008-09-04 11:32:50地主之星
日期:2009-03-30 10:29:22欧洲冠军杯纪念徽章
日期:2009-05-31 09:59:59NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA之星
日期:2010-04-15 14:14:34NBA大富翁
日期:2010-04-15 14:17:22博彩之星
日期:2010-07-12 13:14:39
24#
 楼主| 发表于 2008-8-24 15:17 | 只看该作者
这节的内容让我记忆犹新,痛定思痛,不为别的,就为它让我郁闷了好几天,出现了错误却怎么也找不到原因。事情是这样的:根据练习的要求,我在Object Navigator中创建了多个canvas并且按要求将各个widget分布其上,然后在Form 6i环境中编译成功,随后上传到服务器上重新编译,却总是报有个canvas上的item超界,无法生成可执行文件。检查了许久,发现不了错误,郁闷的重做一遍情况还是如此;无奈,请教同事,告知,在content canvas中添加tab canvas和stacked canvas时,需在content canvas的layout edit中创建,在Object Navigator中创建的将不会出现在content canvas上,因此即使item超界也发现不了,这才如梦方醒,真是麻烦啊!
关于Stacked Canvas尺寸和位置的设置,从属性窗口中发现有两套位置体系:一是Viewport X Position, Viewport Y Position,Viewport Width,Viewport Height;二是Viewport X Position on Canvas,Viewport Y Position on Canvas,Width,Height。试验了一下发现决定Stacked Canvas尺寸和位置的是第一套体系,修改参数后可在layout editor中看出明显的差别。而第二套体系参数修改后Canvas没什么变化,而且看的操作提示中所有Stacked Canvas的Viewport X Position on Canvasà0,Viewport Y Position on Canvasà0,Width,Height值分别比Viewport Width,Viewport Height值略大而已。我想这套体系总是有作用的,只是我不知道而已,请不吝赐教。
对于某个block的scrollbar,是可以修改其canvas属性的,决定scrollbar显示在指定的canvas上。
Tabbed Regions的行为特性:
*主键字段和fixed字段一样,最好放在fixed field stacked canvas,不要放在可变区;
*tab控制列表可从键盘激活(好像没碰到);.
*利用tab键导航item时能够跨越tab页;
*tab页可以根据需要动态地启用和禁用;
*Tabs must remain operable in query by example mode(不理解)

Tab-related Built-ins
Set/Get_tab_page_property (canvas.tabpage...)
– ENABLED      – LABEL      – VISIBLE
Set/Get_canvas_property (canvas...)
– TOPMOST_TAB_PAGE
Set/Get_view_property (canvas...)
– VIEW_X/Y_POS      – HEIGHT     – WIDTH

Tab-related Variables
:SYSTEM.TAB_NEW_PAGE
– name of the tab page the user clicked on
:SYSTEM.EVENT_CANVAS
– name of canvas that owns the newly-selected tab page
:SYSTEM.TAB_PREVIOUS_PAGE
– name of the tab page that was topmost before the user clicked on the new one

Dynamically Changing Tabs
Dynamically hide tabs only at form startup.
– set_tab_page_property(...VISIBLE)
Dynamically enabling/disabling tabs.
– set_tab_page_property(...ENABLED...)

此外是与tab相关的trigger,在About Trigger节介绍。

使用道具 举报

回复
论坛徽章:
259
地主长老
日期:2008-05-16 13:45:41春季摄影比赛纪念奖
日期:2008-06-04 10:35:252008欧洲杯之星
日期:2008-07-01 14:52:28金牌徽章
日期:2008-09-04 11:32:50地主之星
日期:2009-03-30 10:29:22欧洲冠军杯纪念徽章
日期:2009-05-31 09:59:59NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA之星
日期:2010-04-15 14:14:34NBA大富翁
日期:2010-04-15 14:17:22博彩之星
日期:2010-07-12 13:14:39
25#
 楼主| 发表于 2008-8-24 15:18 | 只看该作者
这节练习主要介绍如何动态控制item的显示格式和动态生成非database item。尽管是以currency number为例,对于其他类型的字段,处理方式可以借鉴

1. 动态控制item的显示格式
在Block-level的Post-query trigger和Item-level的 when-validate-item trigger调用handler,控制显示格式。
Eg:
PROCEDURE FORMAT_PRICE(EVENT VARCHAR2) IS
BEGIN
  IF (EVENT IN ('WHEN-VALIDATE-ITEM','POST-QUERY'))
THEN
APP_ITEM_PROPERTY.SET_PROPERTY('LINES.SUGGESTED_PRICE',FORMAT_MASK,      FND_CURRENCY.GET_FORMAT_MASK(:ORDERS.CURRENCY_CODE,GET_ITEM_PROPERTY('LINES.SUGGESTED_PRICE',MAX_LENGTH)));
    APP_ITEM_PROPERTY.SET_PROPERTY('LINES.TOTAL_PRICE',FORMAT_MASK,      FND_CURRENCY.GET_FORMAT_MASK(:ORDERS.CURRENCY_CODE,GET_ITEM_PROPERTY('LINES.TOTAL_PRICE',MAX_LENGTH)));
  ELSE
        FND_MESSAGE.DEBUG('Invalid event passed to lines.format_price '||EVENT);
  END IF;
END FORMAT_PRICE;

使用道具 举报

回复
论坛徽章:
259
地主长老
日期:2008-05-16 13:45:41春季摄影比赛纪念奖
日期:2008-06-04 10:35:252008欧洲杯之星
日期:2008-07-01 14:52:28金牌徽章
日期:2008-09-04 11:32:50地主之星
日期:2009-03-30 10:29:22欧洲冠军杯纪念徽章
日期:2009-05-31 09:59:59NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA之星
日期:2010-04-15 14:14:34NBA大富翁
日期:2010-04-15 14:17:22博彩之星
日期:2010-07-12 13:14:39
26#
 楼主| 发表于 2008-8-24 15:18 | 只看该作者
2. 动态生成非database item
在Block-level的Post-query trigger和Item-level的 when-validate-item trigger调用handler,仍可动态生成非database item的值。前一个trigger在从数据库中获取记录时起作用,后一个trigger在修改记录后起左右,使得非database item随着database item值的改变而改变。
Eg:
PROCEDURE TOTAL_PRICE(EVENT VARCHAR2) IS
BEGIN
  IF (EVENT IN ('WHEN-VALIDATE-ITEM','POST-QUERY'))
THEN
:LINES.TOTAL_PRICE:= NVL(:LINES.ORDERED_QUANTITY,0)*NVL(:LINES.SUGGESTED_PRICE,0);
  ELSE
    FND_MESSAGE.DEBUG('Invalid event passed to lines.total_price '||EVENT);
  END IF;
END TOTAL_PRICE;

使用道具 举报

回复
论坛徽章:
259
地主长老
日期:2008-05-16 13:45:41春季摄影比赛纪念奖
日期:2008-06-04 10:35:252008欧洲杯之星
日期:2008-07-01 14:52:28金牌徽章
日期:2008-09-04 11:32:50地主之星
日期:2009-03-30 10:29:22欧洲冠军杯纪念徽章
日期:2009-05-31 09:59:59NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA之星
日期:2010-04-15 14:14:34NBA大富翁
日期:2010-04-15 14:17:22博彩之星
日期:2010-07-12 13:14:39
27#
 楼主| 发表于 2008-8-24 15:42 | 只看该作者
这节练习主要介绍了在运行时怎样对各种类型的Item(日期、数字、字符串等)进行控制。
    日期型的Item往往会使用Calendar LOV,要点在于:LOV—> ENABLE_LIST_LAMP,Validate from List LOV—>No,Item-level KEY-Listval trigger调用CALENDAR.SHOW;且trigger属性Execution Hierarchy—>Override,fire in enter-query mode—>No。
    Form还经常会用到sequence,往往是在插入记录前,需要一个流水号,作为插入记录的主键字段。
Eg:   
PROCEDURE ORDER_ID(EVENT VARCHAR2) IS
  CURSOR C IS
    SELECT DEM_ORDERS_S.NEXTVAL FROM DUAL;
BEGIN
  IF (EVENT='ON-INSERT') THEN
    OPEN C;
    FETCH C INTO :ORDERS.ORDER_ID;
    IF (C%NOTFOUND) THEN
      CLOSE C;
      RAISE NO_DATA_FOUND;
    END IF;
    CLOSE C;
  ELSE
    FND_MESSAGE.DEBUG('Invalid event passed to orders.order_id: '||EVENT);
  END IF;
END ORDER_ID;
此段代码会放block-level on-insert trigger中被调用,而且应放在 insert_row过程之前执行。
如果有title依赖Master window的Detail window,那么在Master window插入新记录时,应立即随后设置Detail window的title。
Eg:(on-insert trigger)
ORDERS.ORDER_ID('ON-INSERT');
ORDERS.INSERT_ROW;
LINES.LINES_TITLE('ON-INSERT');
除了这些,还有很多控制格式的API,如:APP_MUMBER,APP_DATE,FND_DATE,FND_CURRENCY,需要的时候再去手册中查阅。

使用道具 举报

回复
论坛徽章:
259
地主长老
日期:2008-05-16 13:45:41春季摄影比赛纪念奖
日期:2008-06-04 10:35:252008欧洲杯之星
日期:2008-07-01 14:52:28金牌徽章
日期:2008-09-04 11:32:50地主之星
日期:2009-03-30 10:29:22欧洲冠军杯纪念徽章
日期:2009-05-31 09:59:59NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA之星
日期:2010-04-15 14:14:34NBA大富翁
日期:2010-04-15 14:17:22博彩之星
日期:2010-07-12 13:14:39
28#
 楼主| 发表于 2008-8-24 15:44 | 只看该作者
这节练习主要是介绍窗体上各个widget之间的Dependencies控制。Dependencies
我觉得这种控制的关键在于:1确定具有Dependencies关系的items,2正确设置这种Dependencies控制逻辑,3在恰当的时刻调用这些逻辑。
Dependencies关系有多种,比如说一个item依赖一个item,多个item依赖一个item,一个item依赖多个item等。
控制逻辑也有多种,比如说一个item只在另一个item非空时才被激活;一个Item只在另一个item满足某些特定条件时才被激活;一个item从非激活状态变成激活状态后不能为空;一组Item同时只能有一个Item可被赋值;一组Item如果有一个Item被赋值,其他Item也一定要被赋值;当被依赖的item值发生变化时,依赖项值立刻被清空等。
我们经常会在以下的trigger中调用Dependencies控制逻辑:PRE-RECORD,when-create-record, when-validate-item,when-checkbox-changed, when-radio-changed,when-list-changed 和‘INIT’ 事件。我觉得PRE-RECORD和INIT是在操作数据前初始化这些逻辑,而其他是在item发生变化后验证这些逻辑,满足条件则进行后续的动作。
Eg:
APP_FIELD.SET_DEPENDENT_FIELD(EVENT,
:block.master_item = CONDITION,
’block.dependent_item’);

APP_FIELD.SET_DEPENDENT_FIELD(EVENT,
((:block.master_item1 IS NOT NULL) AND
(:block.master_item2 IS NOT NULL)),
’block.dependent_item’);

APP_FIELD.SET_EXCLUSIVE_FIELD(EVENT,
’block.item1’,
’block.item2’,
’block.item3’);

APP_FIELD.SET_INCLUSIVE_FIELD(EVENT,
’block.item1’,
’block.item2’);

APP_FIELD.SET_REQUIRED_FIELD(EVENT,
(CONDITION),
’block.item’);

使用道具 举报

回复
论坛徽章:
259
地主长老
日期:2008-05-16 13:45:41春季摄影比赛纪念奖
日期:2008-06-04 10:35:252008欧洲杯之星
日期:2008-07-01 14:52:28金牌徽章
日期:2008-09-04 11:32:50地主之星
日期:2009-03-30 10:29:22欧洲冠军杯纪念徽章
日期:2009-05-31 09:59:59NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA之星
日期:2010-04-15 14:14:34NBA大富翁
日期:2010-04-15 14:17:22博彩之星
日期:2010-07-12 13:14:39
29#
 楼主| 发表于 2008-8-24 15:44 | 只看该作者
Oracle 建议使用APP_ITEM_PROPERTY.SET_PROPERTY API函数取代SET_ITEM_PROPERTY (Oracle Forms built-in函数) 动态设置Item的属性。可以设置的属性有:DISPLAYED,ENABLED,ENTERABLE,ALTERABLE (item instance level),ALTERABLE_PLUS (item level),REQUIRED。
设置Item有两种方式:根据Item_ID和根据Item_NAME。
Syntax Using Item ID
item_id := Find_item(’block_name.item_name’);
app_item_property.set_property(item_id,
property_name,
setting);
Example
note_item_id := Find_item(’orders.note’);
app_item_property.set_property(note_item_id,
REQUIRED, PROPERTY_ON);
Syntax Using Block.Item_Name
app_item_property.set_property(
’block_name.item_name’,
property_name,
setting);
Example
app_item_property.set_property(’orders.note’,
DISPLAYED, PROPERTY_OFF);

与之相对应的是可以使用APP_ITEM_PROPERTY.GET_PROPERTY API函数取代GET_ITEM_PROPERTY (Oracle Forms built-in函数) 动态获取Item的属性。
设置Item-level和Item-instance-level属性时需特别的注意,Item-level属性影响所有的记录,而Item-instance-level属性只影响特定的记录(我的理解是当前行)。对于诸如 INSERT_ALLOWED,UPDATEABLE 和 NAVIGABLE 等属性来说,是能够在item level 和 item-instance level重复设置的。如果在item-level 设成OFF, 而在item-instance level设成ON , 重复设置的最终效果仍是OFF。如果同时设了ALTERABLE 和ENABLED ,可能最终效果也不会像预期的那样。所以碰到这样的情况时要特别小心。
     此外,本节还提到一些有关User Profile的知识,好像没什么具体示例,没大搞明白,留待以后研究吧。

使用道具 举报

回复
论坛徽章:
259
地主长老
日期:2008-05-16 13:45:41春季摄影比赛纪念奖
日期:2008-06-04 10:35:252008欧洲杯之星
日期:2008-07-01 14:52:28金牌徽章
日期:2008-09-04 11:32:50地主之星
日期:2009-03-30 10:29:22欧洲冠军杯纪念徽章
日期:2009-05-31 09:59:59NBA季后赛大富翁
日期:2009-06-16 11:48:01NBA之星
日期:2010-04-15 14:14:34NBA大富翁
日期:2010-04-15 14:17:22博彩之星
日期:2010-07-12 13:14:39
30#
 楼主| 发表于 2008-8-24 15:44 | 只看该作者
本节介绍如何在窗体中使用Message。使用Message应该是挺简单的,主要是两个步骤:设置Message和显示Message。

1.        设置Message
我觉得按照是否需要在Message Dictionary定义Message可以分为两种。下图显示的是在Message窗体中定义了一个名为DEMVC_SHIP_BEFORE_ORDER的Message。
        
Oracle建议Name采用大写字母加下划线的命名方式,Application就是需要用到该Message的Application,Language当前语言(应该与后面的翻译有关),Number在显示的时候有时会用到(前面还会带前缀,不填的话就不出现,前缀也会省略),Current Message Text就是要显示的文本了,带’&’的则说明该Message带参数,图中的Message就有&ORDERDATE和&SHIPDATE两个参数。
定义Message信息时除了语法、语义上的注意事项外,还需遵循一些编码规范。比如说:定义的参数最好有特定的含义并且易于区分,尽量不要将一些仅表达语义的短语作为参数传入(因为Oracle在翻译Message的时候默认不会翻译参数,相当于这些参数都是硬编码的)。
在Message Dictionary定义完Message后,在窗体中显示Message之前,还需要在窗体中定义Message。步骤为1FND_MESSAGE.SET_NAME设置MESSAGE_NAME和Application Short Name;2 FND_MESSAGE.SET_TOKEN设置MESSAGE参数,注意必要时对参数进行格式转换。
IF (EVENT = 'WHEN-VALIDATE-ITEM') THEN
IF :ORDERS.DATE_SHIPPED IS NOT NULL THEN
   IF :ORDERS.DATE_SHIPPED < :ORDERS.DATE_ORDERED THEN   
    FND_MESSAGE.SET_NAME('DEM','DEMVC_SHIP_BEFORE_ORDER');  
FND_MESSAGE.SET_TOKEN('ORDERDATE',APP_DATE.DATE_TO_CHARDATE(:ORDERS.DATE_ORDERED),FALSE);
    FND_MESSAGE.SET_TOKEN('SHIPDATE', APP_DATE.DATE_TO_CHARDATE(:ORDERS.DATE_SHIPPED),FALSE);
    FND_MESSAGE.ERROR;
  END IF;
END IF;
有些Message并不需要先在Message Dictionary中定义,只需在窗体中定义后就可直接调用,如:
Example 1
/* Set up a specific string (from a variable) and show it */
FND_MESSAGE.SET_STRING (sql_error_message);
FND_MESSAGE.ERROR;
Example 2
/* Set up a specific string and show it */
FND_MESSAGE.SET_STRING (’Hello World’);
FND_MESSAGE.SHOW;

下例展示了FND_MESSAGE.RETRIEVE函数的用法。我的理解是必须在服务器端执行APP_EXCEPTION.RAISE_EXCEPTION过程后才RETRIEVE到信息。
FND_MESSAGE.SET_NAME (’FND’, ’FLEX_COMPILE_ERROR’);
FND_MESSAGE.SET_TOKEN (’PROCEDURE’, ’My Procedure’);
APP_EXCEPTION.RAISE_EXCEPTION;
/* Retrieve an expected message from the server side,
then show it to the user */
FND_MESSAGE.RETRIEVE;
FND_MESSAGE.ERROR;
/* Then either raise FORM_TRIGGER_FAILURE, or exit
routine*/

再来看下fnd_message.get的用法,我感觉有点像赋值。
fnd_message.set_name(appl_short_name,message_name);
fnd_message.get(window_title);
set_window_property(’WINDOW_NAME’, TITLE,
window_title);

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表