<?xml version="1.0" encoding="UTF-8" ?>
<feed xmlns="http://www.w3.org/2005/Atom">
   <title type="text">강좌</title>
      <updated>2012-02-10T17:44:16+09:00</updated>
   <id>http://www.mungchung.com/xe/lecture/atom</id>
   <link rel="alternate" type="text/html" hreflang="ko" href="http://www.mungchung.com/xe/lecture"/>
   <link rel="self" type="application/atom+xml" href="http://www.mungchung.com/xe/lecture/atom"/>
   <generator uri="http://www.xpressengine.com/" version="1.5.1.6">XpressEngine</generator>
   <entry>
      <title>keyfile을 이용한 ssh 접속 방법</title>
      <id>http://www.mungchung.com/xe/13160</id>
      <published>2010-10-28T16:59:34+09:00</published>
      <updated>2011-05-22T21:48:15+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.mungchung.com/xe/13160"/>
      <link rel="replies" type="text/html" href="http://www.mungchung.com/xe/13160#comment"/>
      <author>
         <name>뭉충닷컴</name>
                  <uri>http://www.mungchung.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;&lt;strong&gt;&lt;span style=&quot;FONT-SIZE: 18px&quot;&gt;keyfile을 이용한 ssh 접속 방법&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;A 서버에서 B 서버로 ssh 접속시에 B 서버의 계정 비밀번호 입력 안하고 접속하는 방법이다.&lt;br /&gt;이 방법은 B서버의 계정 비밀번호를 모를때 유용하다. 또한 keyfile에 암호를 적용하기 때문에 2중 보안이 된다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;FONT-SIZE: 14px&quot;&gt;&lt;strong&gt;&lt;span style=&quot;COLOR: #951015&quot;&gt;서버 설정 방법&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;A서버&lt;br /&gt;&lt;/strong&gt;공개키/개인키를 생성한다.&lt;br /&gt;생성 할때의 키 파일명은 꼭 identity로 해야한다.&lt;br /&gt;&lt;/p&gt;
&lt;table style=&quot;BORDER-BOTTOM: #000000 1px solid; BORDER-LEFT: #000000 1px solid; BACKGROUND-COLOR: #000000; BORDER-TOP: #000000 1px solid; BORDER-RIGHT: #000000 1px solid&quot; border=&quot;0&quot; cellspacing=&quot;0&quot; cellpadding=&quot;1&quot; width=&quot;100%&quot;&gt;
&lt;tbody&gt;
&lt;tr valign=&quot;top&quot;&gt;
&lt;td&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;[SERVER.A:/home1/irteam/.ssh] &lt;/span&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;&lt;span style=&quot;COLOR: #ffef00&quot;&gt;ssh-keygen&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;Generating public/private rsa key pair.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;Enter file in which to save the key (/home1/irteam/.ssh/id_rsa): &lt;/span&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;&lt;span style=&quot;COLOR: #ffef00&quot;&gt;/home1/irteam/.ssh/identity&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;Enter passphrase (empty for no passphrase): &lt;/span&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;&lt;span style=&quot;COLOR: #ffef00&quot;&gt;암호입력&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;Enter same passphrase again: &lt;/span&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;&lt;span style=&quot;COLOR: #ffef00&quot;&gt;암호입력&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;Your identification has been saved in /home1/irteam/.ssh/identity.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;Your public key has been saved in /home1/irteam/.ssh/identity.pub.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;The key fingerprint is:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;50:63:b9:8f:10:03:28:db:34:a1:12:b5:19:75:09:e5 irteam...&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;여기에서의 암호는 공개키의 passphrase이다. (사용자 계정의 암호가 아니다!)&lt;br /&gt;이 암호는 넣어도되고 안넣어도 된다. 단, 암호를 넣으면 이 keyfile를 이용해서 접속시에 여기서 설정한 암호를 넣어야한다. (2중 보안)&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;B서버&lt;/strong&gt;&lt;br /&gt;A서버에서 생성한 공개키를 갖다둔다.&lt;br /&gt;
&lt;table style=&quot;BORDER-BOTTOM: #000000 1px solid; BORDER-LEFT: #000000 1px solid; BACKGROUND-COLOR: #000000; BORDER-TOP: #000000 1px solid; BORDER-RIGHT: #000000 1px solid&quot; border=&quot;0&quot; cellspacing=&quot;0&quot; cellpadding=&quot;1&quot; width=&quot;100%&quot;&gt;
&lt;tbody&gt;
&lt;tr valign=&quot;top&quot;&gt;
&lt;td&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;&amp;nbsp;[SERVER.B:/home1/irteam/.ssh] &lt;span style=&quot;COLOR: #ffef00&quot;&gt;vi authorized_keys&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;vi로 authorized_key 파일 생성해서 A서버의 /home1/irteam/.ssh/identity.pub 파일의 내용을 넣는다.&lt;br /&gt;위와 같이 설정하면 keyfile를 이용한 ssh 접속 설정은 모두 완료한 것이다.&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;COLOR: #ff0000&quot;&gt;주의) A서버에서의 개인키 파일명은 identity, B서버에서의 공개키 파일명은 authorized_keys로 해야한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;FONT-SIZE: 14px&quot;&gt;&lt;strong&gt;&lt;span style=&quot;COLOR: #951015&quot;&gt;접속 방법&lt;/span&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;ssh를 이용해서 아래와 같이 접속하면 keyfile 비밀번호를 물어본다. 이 비밀번호 입력하면 B서버로 접속된다.&lt;/p&gt;
&lt;table style=&quot;BORDER-BOTTOM: #000000 1px solid; BORDER-LEFT: #000000 1px solid; BACKGROUND-COLOR: #000000; BORDER-TOP: #000000 1px solid; BORDER-RIGHT: #000000 1px solid&quot; border=&quot;0&quot; cellspacing=&quot;0&quot; cellpadding=&quot;1&quot; width=&quot;100%&quot;&gt;
&lt;tbody&gt;
&lt;tr valign=&quot;top&quot;&gt;
&lt;td&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;[SERVER.A:/home1/irteam/.ssh] &lt;/span&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;&lt;span style=&quot;COLOR: #ffef00&quot;&gt;ssh -l irteam [서버B 아이피]&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;Enter passphrase for key &apos;/home1/irteam/.ssh/identity&apos;: &lt;span style=&quot;COLOR: #ffef00&quot;&gt;암호입력&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;Last login: Thu Oct 28 16:35:12 2010 from 10.255.255.255&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;COLOR: #ffffff&quot;&gt;[SERVER.B.recruit:/home1/irteam]&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;참고 문서 : &lt;a href=&quot;http://www.ibm.com/developerworks/library/l-keyc.html&quot;&gt;http://www.ibm.com/developerworks/library/l-keyc.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>멀티 브라우저 지원하는 frame, iframe 접근 코딩 방법</title>
      <id>http://www.mungchung.com/xe/8217</id>
      <published>2010-07-21T11:11:57+09:00</published>
      <updated>2011-07-15T02:11:48+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.mungchung.com/xe/8217"/>
      <link rel="replies" type="text/html" href="http://www.mungchung.com/xe/8217#comment"/>
      <author>
         <name>뭉충닷컴</name>
                  <uri>http://www.mungchung.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;&amp;nbsp; 
&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;WIDTH: 559pt; BORDER-COLLAPSE: collapse&quot; border=&quot;0&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; width=&quot;743&quot;&gt;
&lt;colgroup&gt;
&lt;col style=&quot;WIDTH: 35pt; mso-width-source: userset; mso-width-alt: 1682&quot; width=&quot;46&quot;/&gt;
&lt;col style=&quot;WIDTH: 253pt; mso-width-source: userset; mso-width-alt: 12324&quot; width=&quot;337&quot;/&gt;
&lt;col style=&quot;WIDTH: 71pt; mso-width-source: userset; mso-width-alt: 3474&quot; width=&quot;95&quot;/&gt;
&lt;col style=&quot;WIDTH: 40pt; mso-width-source: userset; mso-width-alt: 1938&quot; span=&quot;5&quot; width=&quot;53&quot;/&gt;
&lt;tbody&gt;
&lt;tr style=&quot;HEIGHT: 12pt&quot; height=&quot;16&quot;&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: windowtext 0.5pt solid; BACKGROUND-COLOR: #dbe5f1; WIDTH: 35pt; HEIGHT: 12pt; BORDER-TOP: windowtext 0.5pt solid; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl65&quot; height=&quot;16&quot; width=&quot;46&quot;&gt;종류&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: #dbe5f1; WIDTH: 253pt; BORDER-TOP: windowtext 0.5pt solid; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl65&quot; width=&quot;337&quot;&gt;코드&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: #dbe5f1; WIDTH: 71pt; BORDER-TOP: windowtext 0.5pt solid; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl65&quot; width=&quot;95&quot;&gt;인식유형&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: #dbe5f1; WIDTH: 40pt; BORDER-TOP: windowtext 0.5pt solid; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl65&quot; width=&quot;53&quot;&gt;IE&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: #dbe5f1; WIDTH: 40pt; BORDER-TOP: windowtext 0.5pt solid; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl65&quot; width=&quot;53&quot;&gt;Firefox&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: #dbe5f1; WIDTH: 40pt; BORDER-TOP: windowtext 0.5pt solid; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl65&quot; width=&quot;53&quot;&gt;Safari&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: #dbe5f1; WIDTH: 40pt; BORDER-TOP: windowtext 0.5pt solid; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl65&quot; width=&quot;53&quot;&gt;Opera&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: #dbe5f1; WIDTH: 40pt; BORDER-TOP: windowtext 0.5pt solid; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl65&quot; width=&quot;53&quot;&gt;Chrome&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=&quot;HEIGHT: 12pt&quot; height=&quot;16&quot;&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent; HEIGHT: 36pt; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot; height=&quot;48&quot; rowspan=&quot;3&quot;&gt;Frame&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: #eaf1dd; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl68&quot;&gt;window.frames[&quot;프레임이름&quot;].location.href=&quot;;&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;Object&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=&quot;HEIGHT: 12pt&quot; height=&quot;16&quot;&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; HEIGHT: 12pt; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl67&quot; height=&quot;16&quot;&gt;document.frames[&quot;프레임이름&quot;].location.href=&quot;;&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;Object&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;X&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=&quot;HEIGHT: 12pt&quot; height=&quot;16&quot;&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; HEIGHT: 12pt; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl67&quot; height=&quot;16&quot;&gt;document.getElementsByName(&quot;프레임이름&quot;)[0].src=&quot;;&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;HTML Element&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=&quot;HEIGHT: 12pt&quot; height=&quot;16&quot;&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent; HEIGHT: 60pt; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot; height=&quot;80&quot; rowspan=&quot;5&quot;&gt;Iframe&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: #eaf1dd; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl68&quot;&gt;window.frames[&quot;아이프레임이름&quot;].location.href = &quot;&quot;;&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;Object&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=&quot;HEIGHT: 12pt&quot; height=&quot;16&quot;&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; HEIGHT: 12pt; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl67&quot; height=&quot;16&quot;&gt;document.아이프레임이름.location.href = &quot;&quot;;&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;Object&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=&quot;HEIGHT: 12pt&quot; height=&quot;16&quot;&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; HEIGHT: 12pt; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl67&quot; height=&quot;16&quot;&gt;window.아이프레임이름.location.href = &quot;&quot;;&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;Object&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=&quot;HEIGHT: 12pt&quot; height=&quot;16&quot;&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; HEIGHT: 12pt; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl67&quot; height=&quot;16&quot;&gt;아이프레임이름.location.href = &quot;&quot;;&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;Object&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;&lt;/tr&gt;
&lt;tr style=&quot;HEIGHT: 12pt&quot; height=&quot;16&quot;&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; HEIGHT: 12pt; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl67&quot; height=&quot;16&quot;&gt;document.getElementsByName(&quot;아이프레임이름&quot;)[0].src = &quot;&quot;&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;HTML Element&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;BORDER-BOTTOM: windowtext 0.5pt solid; BORDER-LEFT: black; BACKGROUND-COLOR: transparent; BORDER-TOP: black; BORDER-RIGHT: windowtext 0.5pt solid&quot; class=&quot;xl66&quot;&gt;O&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/colgroup&gt;&lt;/table&gt;
&lt;p&gt;&amp;nbsp; 
&lt;p&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;결론은! &lt;span style=&quot;COLOR: #0000ff&quot;&gt;window.frames[&quot;프레임이름&quot;] 이걸로 접근하는 것이 가장 편하다&lt;/span&gt; -_-;&lt;/p&gt;
&lt;p&gt;그리고 인식유형을 보면 Object인지 HTML Element인지 구분해 두었는데 각 유형에 따라서 사용 할 수 있는 속성이 다르다. 위 표를 보면 알겠지만 url 이동 할때 object는 location.href 속성을 이용하는데 HTML Element는 src 속성을 이용한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;위 방법보다 더 범용적이고 쉬운 방법은 frame에 name 속성외에 id속성을 주면 된다.&lt;br /&gt;(물론 일일이 id 속성을 줘야해서 귀찮은 경우도 있음 -_-)&lt;br /&gt;&amp;lt;frame name=&quot;aaa&quot; id=&quot;aaa&quot;&amp;gt;&amp;lt;/frame&amp;gt;&lt;br /&gt;&amp;lt;iframe name=&quot;aaa&quot; id=&quot;aaa&quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;br /&gt;이와 같이 id 속성까지 같이주면 document.getElementById(&quot;프레임ID&quot;) 로 쉽게 사용할수 있다.&lt;br /&gt;알겠지만 document.getElementById(&quot;&quot;) 이 방법은 id속성이 들어가있는 html element는 모두 한방에 접근 가능하다&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>crontab을 이용한 Tomcat 서버 자동 재시작 shell</title>
      <id>http://www.mungchung.com/xe/5164</id>
      <published>2009-08-28T10:50:48+09:00</published>
      <updated>2010-12-02T09:41:19+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.mungchung.com/xe/5164"/>
      <link rel="replies" type="text/html" href="http://www.mungchung.com/xe/5164#comment"/>
      <author>
         <name>뭉충닷컴</name>
                  <uri>http://www.mungchung.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;P&gt;WEB서버, WAS서버가 죽었을 경우 놀다가다 급히 들어와서 이놈을 살려줘야하는데 이런 귀찮음을 없애고자 3분마다 서버상태를 체크해서&amp;nbsp;서버오류시 지가 알아서 재시작하는 방법이다.&lt;BR&gt;&lt;BR&gt;테스트 환경은 다음과 같다.&lt;BR&gt;OS : 레드햇 리눅스&lt;BR&gt;WAS서버 : 톰캣 6.0&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#882222 size=2&gt;1. 웹root에 아래 내용만 넣은 checkLive.jsp 파일을 생성한다.&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;pre class=&quot;brush: plain;toolbar: false;&quot;&gt;success&lt;/pre&gt;
&lt;P&gt;&lt;A href=&quot;http://111.111.111:8080/checkLive.jsp&quot;&gt;http://111.111.111:8080/checkLive.jsp&lt;/A&gt; 실행해서 success 란 메시지가 정상적으로 뿌려지는지 확인한다.&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#882222 size=2&gt;2. autoRestartServer.sh 파일 생성&lt;/FONT&gt;&lt;BR&gt;&lt;/STRONG&gt;적당한 위치(여기선 /home1/irteam/script/)에 생성해서 다음 내용 넣는다.&lt;/P&gt;
&lt;pre class=&quot;brush: plain;&quot;&gt;#!/bin/sh
##### step 1
export JAVA_HOME=/home1/irteam/jdk/jdk1.6.0_13
export PATH=&quot;$PATH:$JAVA_HOME/bin&quot;
export CATALINA_HOME=/home1/irteam/tomcat/
export PATH=&quot;$PATH:$CATALINA_HOME/bin&quot;
export checkFile=/home1/irteam/script/checkLive.jsp
export nowDate=`date +%Y-%m-%d%t%H:%M`

##### step 2
cd /home1/irteam/script
wget http://111.111.111.111:8080/checkLive.jsp

##### step 3
if [ -r &quot;$checkFile&quot; ] ; then
    echo &quot;$nowDate 정상!&quot;
    export file_content=&quot;`cat $checkFile`&quot;
    rm -rf $checkFile
    if [ $file_content != &quot;success&quot; ] ; then
       /home1/irteam/tomcat/bin/shutdown.sh
       sleep 10
       /home1/irteam/tomcat/bin/startup.sh
    fi
else
    echo &quot;$nowDate 실패!&quot;
    /home1/irteam/tomcat/bin/shutdown.sh
    sleep 10
    /home1/irteam/tomcat/bin/startup.sh
    echo &quot;$nowDate 서버 재시작 완료!&quot;
fi&lt;/pre&gt;
&lt;P&gt;chmod 744 autoRestartServer.sh 해서 실행권한 준다.&lt;BR&gt;그리고 나서 이 shell 파일 실행시켜서 정상작동하는지 확인한다.&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;step 1&lt;/STRONG&gt;&lt;BR&gt;그냥 /home1/irteam/script/autoRestartServer.sh 실행시킬 경우에는 실행이 되지만 이 걸 crontab에 등록할 경우에는&amp;nbsp;자바홈, 톰캣홈을 못찾는 경우가 생긴다. 그래서 shell 실행시 필요한 환경변수인 JAVA_HOME, CATALINA_HOME 등을 직접 선언해준다.&lt;BR&gt;&lt;STRONG&gt;step 2&lt;/STRONG&gt;&lt;BR&gt;리눅스의 wget 명령어를 이용해서 &lt;A href=&quot;http://111.111.111.111:8080/checkLive.jsp&quot;&gt;http://111.111.111.111:8080/checkLive.jsp&lt;/A&gt;&amp;nbsp;파일의 내용을 가져온다. 접속 이 정상적이라면 checkLive.jsp 파일을 다운받는다. 접속이 정상적이지 않다면 오류가 발생하면서 이 파일을 다운받지 못한다.&lt;BR&gt;&lt;STRONG&gt;step 3&lt;/STRONG&gt;&lt;BR&gt;checkLive.jsp 파일이&amp;nbsp;존재하는지&amp;nbsp;확인후 그 파일 내용이 success라 적혀있으면 정상적으로 서버가 동작중것이고 그렇지 않다면 서버오류로 인식해서 톰캣서버를 재시작한다.&lt;BR&gt;&lt;BR&gt;&lt;STRONG&gt;&lt;FONT color=#882222 size=2&gt;3. crontab에 등록&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;pre class=&quot;brush: plain;toolbar: false;&quot;&gt;## tomcat server auto restart
*/3 * * * * /home1/irteam/script/autoRestartServer.sh &amp;gt;&amp;gt; /home1/irteam/script/autoRestartServer.log&lt;/pre&gt;
&lt;P&gt;3분마다 체크하도록 crontab에 등록한다. 체크한 로그는 autoRestartServer.log에 기록되도록 해서 나중에 서버의 동작 상태를 확인 할 수 있도록 한다.&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;&lt;BR&gt;원래 초기버젼은&amp;nbsp;3분마다 무조건 서버를 재시작하는하는 방식이였다. 이 방식의 경우 서버 실행중에 또 서버를 실행하는 것으로 나중에 실행된 것은 내부적으로 오류를 발생하면서 종료된다. 실제, 이런 방식을 이용해도 실제 서비스에는 문제가 없으나 간혹가다가 리눅스상에서 불필요한 PID들이 생기는 경우가 있고 주기적으로 오류메시지가 발생한다는것이 좀 찝찝한 구석이 있다.&lt;BR&gt;&lt;BR&gt;두번째로 시도한 방식이 톰캣PID 존재여부로 서버중지여부를 판단해서 서버재시작shell을 만들었는데 이 방식은 톰캣서버가 비정상적으로 종료될경우 찌꺼기 같은 톰캣PID들이 남아있어서 서버중지여부를 판단할수 없는 경우가 있었다.&lt;BR&gt;&lt;BR&gt;그래서 이것저것&amp;nbsp;시도해본 결과 좀 번거롭더라도 주기적으로 웹서버에 연결해서 서버상태를 체크하는 방식을 사용하게 된것이다.&lt;BR&gt;&lt;BR&gt;&lt;/P&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>자바스크립트로 각 form의 element(요소)에 접근 방법</title>
      <id>http://www.mungchung.com/xe/4197</id>
      <published>2008-09-11T18:49:12+09:00</published>
      <updated>2010-12-30T14:51:41+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.mungchung.com/xe/4197"/>
      <link rel="replies" type="text/html" href="http://www.mungchung.com/xe/4197#comment"/>
      <author>
         <name>뭉충닷컴</name>
                  <uri>http://www.mungchung.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;style type=&quot;text/css&quot;&gt;
p {font-size:14px}
td {font-size:9pt}
.tr_css {background-color:white;text-align:center;height:24px}
.title {font-weight:bold;color:brown;height:30px}
&lt;/style&gt;


&lt;p&gt;form의 element에 스크립트로 접근하는 방식들을 정리해보았다.
&lt;br&gt;각 브라우저별로 테스트 했으니 참고 하면 된다.

&lt;br&gt;&lt;br&gt;
&lt;br&gt;IE : 익스플로러 7
&lt;br&gt;SF : 사파리 3
&lt;br&gt;FF : FireFox 3
&lt;br&gt;Chrome : 크롬
&lt;/p&gt;

&lt;form name=&quot;form1&quot;&gt;

&lt;table&gt;
    &lt;tr class=&quot;title&quot;&gt;
        &lt;td&gt;1. form의 element에 name으로 접근&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;table&gt;
    &lt;tr&gt;
        &lt;td&gt;&lt;input type=&quot;text&quot; value=&quot;우후훗!&quot; name=&quot;txt1&quot;&gt;&lt;/td&gt;
        &lt;td&gt;&amp;lt;input type=&quot;text&quot; value=&quot;우후훗!&quot; &lt;font color=red&gt;&lt;b&gt;name=&quot;txt1&quot;&lt;/b&gt;&lt;/font&gt;&amp;gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;

&lt;table width=&quot;700&quot; border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;1&quot; bgcolor=&quot;cccccc&quot;&gt;
    &lt;tr align=&quot;center&quot; bgcolor=&quot;f4f4f4&quot; height=&quot;25&quot; style=&quot;font-weight:bold&quot;&gt;
        &lt;td width=&quot;500&quot;&gt;접근 방법&lt;/td&gt;
        &lt;td width=&quot;50&quot;&gt;실행&lt;/td&gt;
        &lt;td width=&quot;150&quot;&gt;브라우저&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.form1.txt1.value&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.form1.txt1.value);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE, SF, FF, Chrome&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.getElementsByName(&apos;txt1&apos;)[0].value&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.getElementsByName(&apos;txt1&apos;)[0].value);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE, SF, FF, Chrome&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.getElementsByTagName(&apos;input&apos;).item(&apos;txt1&apos;,0).value&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.getElementsByTagName(&apos;input&apos;).item(&apos;txt1&apos;,0).value);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE, SF, FF, Chrome&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.getElementById(&apos;txt1&apos;).value&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.getElementById(&apos;txt1&apos;).value);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.form1.namedItem(&apos;txt1&apos;).value&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.form1.namedItem(&apos;txt1&apos;).value);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.form1.elements[&apos;txt1&apos;].value&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.form1.elements[&apos;txt1&apos;].value);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE, SF, FF, Chrome&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;

&lt;table&gt;
    &lt;tr class=&quot;title&quot;&gt;
        &lt;td&gt;2. form의 element에 ID로 접근&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;table&gt;
    &lt;tr&gt;
        &lt;td&gt;&lt;input type=&quot;text&quot; value=&quot;우후훗!&quot; id=&quot;txt2&quot;&gt;&lt;/td&gt;
        &lt;td&gt;&amp;lt;input type=&quot;text&quot; value=&quot;우후훗!&quot; &lt;font color=red&gt;&lt;b&gt;id=&quot;txt2&quot;&lt;/b&gt;&lt;/font&gt;&amp;gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;

&lt;table width=&quot;700&quot; border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;1&quot; bgcolor=&quot;cccccc&quot;&gt;
    &lt;tr align=&quot;center&quot; bgcolor=&quot;f4f4f4&quot; height=&quot;25&quot; style=&quot;font-weight:bold&quot;&gt;
        &lt;td width=&quot;500&quot;&gt;접근 방법&lt;/td&gt;
        &lt;td width=&quot;50&quot;&gt;실행&lt;/td&gt;
        &lt;td width=&quot;150&quot;&gt;브라우저&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.form1.txt2.value&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.form1.txt2.value);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE, SF, FF, Chrome&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.getElementsByName(&apos;txt2&apos;)[0].value&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.getElementsByName(&apos;txt2&apos;)[0].value);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.getElementsByTagName(&apos;input&apos;).item(&apos;txt2&apos;,0).value&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.getElementsByTagName(&apos;input&apos;).item(&apos;txt2&apos;,0).value);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE, SF, FF, Chrome&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.getElementById(&apos;txt2&apos;).value&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.getElementById(&apos;txt2&apos;).value);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE, SF, FF, Chrome&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.form1.namedItem(&apos;txt2&apos;).value&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.form1.namedItem(&apos;txt2&apos;).value);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.form1.elements[&apos;txt2&apos;].value&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.form1.elements[&apos;txt2&apos;].value);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE, SF, FF, Chrome&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;

&lt;table&gt;
    &lt;tr class=&quot;title&quot;&gt;
        &lt;td&gt;3. form에 중복된 이름의 element가 있을 경우 접근 방법&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;table&gt;
    &lt;tr&gt;
        &lt;td&gt;&lt;input type=&quot;text&quot; value=&quot;우후훗 1&quot; name=&quot;txt3&quot; size=&quot;10&quot;&gt;&lt;input type=&quot;text&quot; value=&quot;우후훗 2&quot; name=&quot;txt3&quot; size=&quot;10&quot;&gt;&lt;/td&gt;
        &lt;td&gt;&amp;lt;input type=&quot;text&quot; value=&quot;우후훗 1&quot; &lt;font color=red&gt;&lt;b&gt;name=&quot;txt3&quot;&lt;/b&gt;&lt;/font&gt;&amp;gt;&amp;lt;input type=&quot;text&quot; value=&quot;우후훗 2&quot; &lt;font color=red&gt;&lt;b&gt;name=&quot;txt3&quot;&lt;/b&gt;&lt;/font&gt;&amp;gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;

&lt;table width=&quot;700&quot; border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;1&quot; bgcolor=&quot;cccccc&quot;&gt;
    &lt;tr align=&quot;center&quot; bgcolor=&quot;f4f4f4&quot; height=&quot;25&quot; style=&quot;font-weight:bold&quot;&gt;
        &lt;td width=&quot;500&quot;&gt;접근 방법&lt;/td&gt;
        &lt;td width=&quot;50&quot;&gt;실행&lt;/td&gt;
        &lt;td width=&quot;150&quot;&gt;브라우저&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.getElementsByName(&apos;txt3&apos;)[0].value
        &lt;xmp&gt;for (var i=0; i&lt;document.getElementsByName(&apos;txt3&apos;).length; i++) {
    alert(document.getElementsByName(&apos;txt3&apos;)[i].value);
}&lt;/xmp&gt;
        &lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.getElementsByName(&apos;txt3&apos;)[0].value);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE, SF, FF, Chrome&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.getElementsByTagName(&apos;input&apos;).item(&apos;txt3&apos;,0).value
        &lt;xmp&gt;for (var i=0; i&lt;document.getElementsByTagName(&apos;input&apos;).item(&apos;txt3&apos;).length; i++) {
    alert(document.getElementsByTagName(&apos;input&apos;).item(&apos;txt3&apos;,i).value);
}&lt;/xmp&gt;&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.getElementsByTagName(&apos;input&apos;).item(&apos;txt3&apos;,0).value);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE, SF, FF, Chrome&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;br&gt;
&lt;table width=&quot;700&quot;&gt;
    &lt;tr&gt;
        &lt;td&gt;

form의 element가 중복 될 수도 있고 아닐수도 있으면 위의 2가지 방법중 하나를 이용해서 스크립트 작성하는게 편하다.&lt;br&gt;
&lt;br&gt;
위의 2가지 접근방법말고 다른 스크립트 코드들은 
element가 하나면 일반 element 되고 2개 이상이면 배열이 되어버린다.&lt;br&gt;
&lt;br&gt;
이러한 element 중복여부의 대표적인 예가 행추가/행삭제이다.
행이 하나면 element가 하나여서 일반 element가 되는데
행이 두개 이상이면 element가 배열이 되어 버린다. 
이 경우 스크립트를 이용해서 접근하려고 하면 해당 element가 하나일 때와 2개 이상 일때 구분해서 처리해 줘야한다.
&lt;xmp&gt;if (typeof(document.form1.txt3.length) == &quot;undefined&quot;) {
    alert(document.form1.txt3.value);
} else {
    for (var i=0; i&lt;document.form1.txt3.length; i++) {
        alert(document.form1.txt3[i].value);
    }
}&lt;/xmp&gt;

딱 봐도 엄청 귀찮은 작업이다. -_-
본인도 예전에는 저와같은 방식으로 이용했다 -_- 

&lt;br&gt;&lt;br&gt;위의 방식으로의 또 다른 문제점은 form의 select 요소에 접근 할 때이다.
위의 코드에서는 배열여부를 document.form1.txt3.length 의 typeof 값이 undefined 인지 여부를 통해서 판단했는데
select의 경우에는 위의 구문대로 하면 option의 갯수를 가져와 버린다. 그래서 select 는 또 다른 방식으로 배열 여부를 구분해야한다.

&lt;br&gt;&lt;br&gt;그래서 얻은 결론은 행추가/행삭제 같은 element가 중복 될 수도 있고 안될 수도 있다면
위의 2 가지 방법으로 element에 접근하는 것이 편하다는 것이다
        &lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;

&lt;br&gt;&lt;br&gt;
&lt;table&gt;
    &lt;tr class=&quot;title&quot;&gt;
        &lt;td&gt;4. form의 element의 사용자 정의 속성 접근&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;table&gt;
    &lt;tr&gt;
        &lt;td&gt;&lt;input type=&quot;text&quot; myTag=&quot;우후훗!&quot; name=&quot;txt4&quot;&gt;&lt;/td&gt;
        &lt;td&gt;&amp;lt;input type=&quot;text&quot; &lt;font color=red&gt;&lt;b&gt;myTag=&quot;우후훗!&quot;&lt;/b&gt;&lt;/font&gt; name=&quot;txt4&quot;&amp;gt;&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;

&lt;table width=&quot;700&quot; border=&quot;0&quot; cellpadding=&quot;2&quot; cellspacing=&quot;1&quot; bgcolor=&quot;cccccc&quot;&gt;
    &lt;tr align=&quot;center&quot; bgcolor=&quot;f4f4f4&quot; height=&quot;25&quot; style=&quot;font-weight:bold&quot;&gt;
        &lt;td width=&quot;500&quot;&gt;접근 방법&lt;/td&gt;
        &lt;td width=&quot;50&quot;&gt;실행&lt;/td&gt;
        &lt;td width=&quot;150&quot;&gt;브라우저&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.form1.txt4.myTag&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.form1.txt4.myTag);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.getElementsByName(&apos;txt4&apos;)[0].myTag&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.getElementsByName(&apos;txt4&apos;)[0].myTag);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.getElementsByTagName(&apos;input&apos;).item(&apos;txt4&apos;,0).myTag&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.getElementsByTagName(&apos;input&apos;).item(&apos;txt4&apos;,0).myTag);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.getElementById(&apos;txt4&apos;).myTag&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.getElementById(&apos;txt4&apos;).myTag);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.form1.namedItem(&apos;txt4&apos;).myTag&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.form1.namedItem(&apos;txt4&apos;).myTag);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.form1.elements[&apos;txt4&apos;].myTag&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.form1.elements[&apos;txt4&apos;].myTag);&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td height=&quot;2&quot; colspan=&quot;3&quot; bgcolor=&quot;cccccc&quot;&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.form1.txt4.getAttribute(&apos;myTag&apos;)&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.form1.getAttribute(&apos;myTag&apos;));&quot;&gt;&lt;/td&gt;
        &lt;td&gt;모두 안됨&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.getElementsByName(&apos;txt4&apos;)[0].getAttribute(&apos;myTag&apos;)&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.getElementsByName(&apos;txt4&apos;)[0].getAttribute(&apos;myTag&apos;));&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE, SF, FF, Chrome&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.getElementsByTagName(&apos;input&apos;).item(&apos;txt4&apos;,0).getAttribute(&apos;myTag&apos;)&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.getElementsByTagName(&apos;input&apos;).item(&apos;txt4&apos;,0).getAttribute(&apos;myTag&apos;));&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.getElementById(&apos;txt4&apos;).getAttribute(&apos;myTag&apos;)&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.getElementById(&apos;txt4&apos;).getAttribute(&apos;myTag&apos;));&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.form1.namedItem(&apos;txt4&apos;).getAttribute(&apos;myTag&apos;)&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.form1.namedItem(&apos;txt4&apos;).getAttribute(&apos;myTag&apos;));&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr class=&quot;tr_css&quot;&gt;
        &lt;td align=&quot;left&quot;&gt;document.form1.elements[&apos;txt4&apos;].getAttribute(&apos;myTag&apos;)&lt;/td&gt;
        &lt;td&gt;&lt;input type=&quot;button&quot; value=&quot;실행&quot; onclick=&quot;alert(document.form1.elements[&apos;txt4&apos;].getAttribute(&apos;myTag&apos;));&quot;&gt;&lt;/td&gt;
        &lt;td&gt;IE, SF, FF, Chrome&lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;/form&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>ERwin 에서 Logical의 컬럼명을 코멘트(Comment)로 변경하기</title>
      <id>http://www.mungchung.com/xe/4193</id>
      <published>2008-01-16T23:19:31+09:00</published>
      <updated>2011-03-22T18:42:47+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.mungchung.com/xe/4193"/>
      <link rel="replies" type="text/html" href="http://www.mungchung.com/xe/4193#comment"/>
      <author>
         <name>뭉충닷컴</name>
                  <uri>http://www.mungchung.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;
어렵지 않다. 
&lt;br&gt;본인이 귀찮음을 무릅쓰고 캡쳐까지 떴다. (대신에 설명글 짧게 쓴다 -_-)
&lt;br&gt;조낸 그대로 따라하는거다.
&lt;br&gt;&lt;br&gt;*) 첨부파일은 샘플로 사용한 쿼리문
&lt;br&gt;*) 코멘트(Comment)는 &lt;u&gt;오라클에 있는 컬럼의 코멘트&lt;/u&gt; 값이다. 즉 MS-SQL은 안된다
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;1. 모델을 Logical로 선택한 후에 왼쪽 트리에서 Domains를 더블클릭 한다.
&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(혹은 [Model] - [Model Dictionary] 메뉴를 선택)&lt;/p&gt;

&lt;p style=margin-left:20&gt;&lt;img src=/mianamssi/img/zboard/erwin_comment/01.gif&gt;&lt;/p&gt;

&lt;p&gt;2. 빨간색 박스부분의 값을 %AttDomain 에서 %ColumnComment 로 변경한 후 OK 클릭
&lt;p style=margin-left:20&gt;&lt;img src=/mianamssi/img/zboard/erwin_comment/02.gif&gt;&lt;/p&gt;

&lt;p&gt;3. [Model] - [Attributes] 메뉴를 클릭&lt;/p&gt;
&lt;p style=margin-left:20&gt;&lt;img src=/mianamssi/img/zboard/erwin_comment/03.gif&gt;&lt;/p&gt;

&lt;p&gt;4. Attributes 창에서 왼쪽 하단에 Reset 버튼 클릭&lt;/p&gt;
&lt;p style=margin-left:20&gt;&lt;img src=/mianamssi/img/zboard/erwin_comment/04.gif&gt;&lt;/p&gt;

&lt;p&gt;5. 아래 빨간색 박스처럼 Reset all Attributes in Model 선택, Name 체크
   해준 후에 OK 클릭&lt;/p&gt;
&lt;p style=margin-left:20&gt;&lt;img src=/mianamssi/img/zboard/erwin_comment/05.gif&gt;&lt;/p&gt;

&lt;p&gt;6. 아래 화면과 같이 Attribute 값들이 Comment의 값으로 대체 된 것이 보인다.&lt;/p&gt;
&lt;p style=margin-left:20&gt;&lt;img src=/mianamssi/img/zboard/erwin_comment/06.gif&gt;&lt;/p&gt;

&lt;p&gt;7. ERD에 Comment가 적용 된 화면&lt;/p&gt;
&lt;p style=margin-left:20&gt;&lt;img src=/mianamssi/img/zboard/erwin_comment/07.gif&gt;&lt;/p&gt;
&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Tabular Data Control 마지막 강좌!</title>
      <id>http://www.mungchung.com/xe/4192</id>
      <published>2007-06-14T20:22:39+09:00</published>
      <updated>2011-03-19T09:50:27+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.mungchung.com/xe/4192"/>
      <link rel="replies" type="text/html" href="http://www.mungchung.com/xe/4192#comment"/>
      <author>
         <name>뭉충닷컴</name>
                  <uri>http://www.mungchung.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p align=center&gt;&lt;font color=red size=7&gt;&lt;b&gt;TDC 사용하지 말자!&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;



&lt;p&gt;근 6년간 TDC를 간간히 사용해 왔는데 나의 결론은 &quot;TDC를 사용하지 말자&quot;로 내렸다.
혹 내가 적은 이 허접한 강좌들을 보고 TDC를 적용해 보신 분들에게는 정말 미안하다.&lt;/p&gt;

&lt;p&gt;처음 TDC를 접했을 땐 새로운 방식의 기술, 디자이너와 개발자와의 분리 등등 여러가지 이점이
많이 보였는데 지금와서 보면 단 한가지 단점 때문에 좋은 점 모두가 불필요한 것이 되었다.&lt;/p&gt;

&lt;p&gt;그 단점은 다름아닌 99% 컴퓨터에서는 잘되는데 1% 컴퓨터에서 말썽을 부린다는 점이다.
(1%의 오류는 모집단을 샘플링해서 통계치를 추정한 것은 아니고 경험상 오류전화오는 횟수를 대강 산정한것이다.-_-)&lt;/p&gt;

&lt;p&gt;똑같은 코드인데 어느 PC는 되고 어느 PC는 안된다.
보통 이럴 경우 익스플로러 버젼, 운영체제가 버젼, PC에 설치되어 있는 소프트웨어 등등 살펴봐서 오류나는 PC와 안나는 PC와의 다른점을 찾으려고
노력할 것이다. 물론 나도 이런 노력 다 해봤다. 별의 별 방법을 다 찾아봤다. 그래도 안되는 PC는 이상하게 안된다 -_-;&lt;/p&gt;

&lt;p&gt;TDC가 내가 직접 제작한 컴퍼넌트도 아니고 MS사에서 기본적으로 윈도우에 포함하는 컴퍼넌트인데도
이렇게 오류가 나타나니...별다른 대안없이 전화오면 그냥 &quot;다른 PC 가서 하세요&quot; 라고 넘겼다.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;최근에 나타난 또 하나의 TDC 관련 오류는 익스플로워 업데이트 되면서 잘되던 코드에 에러가 나면서 익스플로워가 다운된다.
물론 이것은 원인 파악 결과 HTML 코딩에 실수가 있어서 나타난 오류지만 예전엔 되던것이 익스플로워 업데이트 되면서
TDC와 관련해서 뭔가 바뀐것 같다.&lt;/p&gt;

&lt;p&gt;이런 상황이다보니 굳이 복잡하게 TDC를 사용할 필요성을 못 느낀다.&lt;/p&gt;


&lt;p&gt;스크립트 언어는 스크립트처럼 위에서 부터 아래로 쭈루룩~ 코딩하는게 최고인것 같다.
신기술 이용, 독특한 개념들 적용하는 것은 좋지만, 문제는 이럴 경우 일반성이 떨어지다보니 추후에 문제될 소지가 다분하다.
그래서 최근들어서는 코딩에 멋부릴 필요 없이 가장 일반적으로 단순하게 짜는 것이 최고라는 생각이 든다.
&lt;/p&gt;


&lt;p&gt;정말 어떤 닷넷 고수 말처럼 &lt;font color=brown&gt;&lt;u&gt;&quot;Simple is Best&quot;&lt;/u&gt;&lt;/font&gt;이다 -_-&lt;/p&gt;



&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>ASP로 웹 어플리케이션 주소 사용하기</title>
      <id>http://www.mungchung.com/xe/4190</id>
      <published>2006-12-10T01:21:14+09:00</published>
      <updated>2010-12-30T14:51:41+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.mungchung.com/xe/4190"/>
      <link rel="replies" type="text/html" href="http://www.mungchung.com/xe/4190#comment"/>
      <author>
         <name>뭉충닷컴</name>
                  <uri>http://www.mungchung.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;asp에선 자바의 서블릿이나 닷넷의 웹어플리케이션과 같은 주소를 나타낼 수 없다.
왜냐? MS에서 asp 내놓을때 정책상으로 일부로 그렇게 한것인지 어떤지는 모르겠다.
그냥 해보니 그런 주소를 나타낼수가 없었다.
간혹 이 말이 무슨소리인지 모르는 분들이 있을까봐 예를 들어보겠다.&lt;/p&gt;

&lt;pre class=&quot;code&quot;&gt;
http://www.mungchung.com/WebApp
http://www.mungchung.com/WebApp/
&lt;/pre&gt;

&lt;p&gt;이 2개의 주소가 있다. 뭐가 다른가? 뒤에 슬래쉬가 붙고 안붙고의 차이다.
요게 아무것도 아닌것 같지만 어렸을 당시엔 충격적이였다. 그 당시 어떤 사이트를 보니
뒤에 슬래쉬가 안붙고도 웹페이지가 나오는것을 보고 asp로 저런 기능이 있나해서 몇일동안 찾은적이있다.
결국 찾지 못하고 좌절하다가 JSP 개발할일이 있어서 서블릿을 공부하던중 슬래쉬 안붙이는 방법을 알게 되었다.
서블릿에서 Web Application 방식을 이용하면 뒤에 슬래쉬 안붙는 URL 처리가 되었던것이다.
(닷넷 또한 Web Application 이 생겨서 이 URL 처리가 가능해졌다.)&lt;/p&gt;



&lt;p&gt;asp에선..아니 정확히 말하면 IIS 5.0 에선 http://www.mungchung.com/WebApp 요런식의 주소에 요청에 들어오면
일단 WebApp 파일이 있는지 부터 검사를 한다. 만일 파일이 있다면(확장자가 안붙은 파일이겠죠) 다운로드 창이 떠서
WebApp 파일을 다운 받게 한다.
파일이 없다면 WebApp 폴더나 가상디렉토리로 인식해서 http://www.mungchung.com/WebApp/ 로 리다이렉트 시켜버린다.
&lt;/p&gt;

&lt;pre class=&quot;code&quot;&gt;
&lt;b&gt;참고&lt;/b&gt;
이런 IIS 방식때문에 코딩할때 http://www.mungchung.com/WebApp 라 적는것보다 
http://www.mungchung.com/WebApp/ 라고 뒤에슬래쉬 붙이는게 
서버에 한번 더 왔다 갔다 안해서 부하를 줄일 수 있다.
&lt;/pre&gt;


&lt;p&gt;때문에 asp로 뒤에 슬래쉬 안붙은 URL을 나타낼 수가없었다.
하지만! 에러 페이지의 트릭을 이용하면 가능하다. 이것의 대표적인 예가 싸이월드다.
싸이월드 주소를 보면 http://www.cyworld.com/아이디  이런식으로 슬래쉬 없어도 아이디에 해당하는 사용자의 홈으로 이동한다.
이것의 실제 주소느 http://minihp.cyworld.nate.com/pims/main/pims_main.asp?tid=000000&amp;urlstr=&amp;urlstrsub= 이런 모양이지만
그런식의 처리를 해서 사용자들이 쉽게 주소를 외울 수 있게해준다.
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;지금부터 이렇게 처리하는 방법을 간략하게 적어보려고한다.
이해를 쉽게 돕기 위해서 예제 프로그램을 간략하게 만들었다. 예제 프로그램은 다음과 같다.
&lt;/p&gt;

&lt;p&gt;자신의 홈페이지가 하나 있다고하자(물론 이 홈피는 asp로 만들어진 홈이여야한다)
사용자들이 http://www.myhome.com/empas 라고 적으면 바로 엠파스로 접속 할 수 있고
http://www.myhome.com/mungchung 라고 치면 나의 홈피로 접속 할수 있도록 할것이다.
&lt;/p&gt;


&lt;a class=name&gt;첫째. DB부터 구축한다. &lt;/a&gt;
&lt;p&gt;첨부파일 다운받아서 tb_url_create.sql 에 있는 쿼리문을 쿼리분석기에서 실행시킨다.
참고로 테이블명은 TB_URL 이고 컬럼은 url_name, url_title, url 이렇게 딱 3개만 있다.
url_name은 주소뒤에 붙을 명칭이다. http://www.myhome.com/mungchung 요런식의 주소에서 mungchung 에 해당된다.
url_title은 익스플로워 제목에 보여질 부분이다.(컬럼은 만들어두고 사용 안함 -_-)
url은 mungchung가 이동할 URL이다. 즉! http://www.mungchung.com 을 말한다.
&lt;/p&gt;

&lt;a class=name&gt;둘째. 에러 페이지를 만든다.&lt;/a&gt;
&lt;p&gt;일단 코드 전체를 보자.  아래 코드 404_error_redirect.asp로 저장한 후 웹서버 루트디렉토리 안에 넣는다.
(귀찮다면 첨부파일 다운받아도 된다.)&lt;/p&gt;

&lt;xmp class=&quot;code&quot;&gt;
&lt;%
    Option Explicit

    &apos; DB 관련 변수
    Dim DBCon
    Dim strConn
    Dim strSql
    Dim rs

    Dim strQueryString
    Dim strServerName
    Dim strServerPort
    Dim errorNum
    Dim errorURL
    Dim url_name
    Dim url_param
    Dim instr_url

    Dim db_url_name
    Dim db_url_title
    Dim db_url

    &apos; DB 연결 문자 변수
    strConn = strConn&amp;&quot;Provider=SQLOLEDB.1;Persist Security Info=True;&quot;
    strConn = strConn&amp;&quot;Data Source=localhost;&quot;     &apos; Server Name
    strConn = strConn&amp;&quot;User ID=;&quot;                &apos; User ID
    strConn = strConn&amp;&quot;Password=;&quot;     &apos; User Password
    strConn = strConn&amp;&quot;Initial Catalog=TEST;&quot; &apos; DataBase

    Set DBCon = Server.CreateObject(&quot;ADODB.Connection&quot;)
    DBCon.Open strConn


    strQueryString  = Request.ServerVariables(&quot;QUERY_STRING&quot;)
    strServerName   = &quot;http://&quot;&amp;Request.ServerVariables(&quot;SERVER_NAME&quot;)&amp;&quot;/&quot;
    strServerPort   = Request.ServerVariables(&quot;SERVER_PORT&quot;)

    &apos; 에러번호와 URL을 받아온다.
    errorNum = (Split(strQueryString,&quot;;&quot;))(0)
    errorURL = (Split(strQueryString,&quot;;&quot;))(1)

    if errorNum = &quot;404&quot; and right(errorURL,1) &lt;&gt; &quot;/&quot; then
        url_name = replace(errorURL,strServerName,&quot;&quot;)
        instr_url = InStr(url_name,&quot;?&quot;)

        &apos; URL 뒤에 QueryString 가 있을 경우
        if instr_url &gt; 0 then
            url_param = mid(url_name,instr_url+1, len(url_name)-instr_url)
            url_name = left(url_name,instr_url-1)
        end if

        &apos; 테이블을 검사해서 등록된 주소인지 확인한다.
        strSql = &quot;Select url_name, url_title, url From TB_URL Where url_name=&apos;&quot; &amp; url_name &amp; &quot;&apos;&quot;
        Set rs = DBCon.Execute(strSql)
        if rs.eof then
            &apos; 등록된 주소가 아니면 에러페이지 보여주는 함수 호출
            Call ErrorPage_404(errorURL)
        else
            db_url_name = rs(0)
            db_url_title= rs(1)
            db_url      = rs(2)

            &apos; URL 뒤에 Query String가 있었다면 URL뒤에 붙여준다.
            if url_param &lt;&gt; &quot;&quot; then
                db_url = db_url &amp; &quot;?&quot; &amp; url_param
            end if

            &apos; 등록된 주소로 이동시킨다.
            Call UrlFramePage(db_url_name, db_url)
        end if
    end if


    rs.close
    Set rs = nothing
    DBCon.close
    Set DBCon = nothing

    &apos;---------------------------------------------------
    &apos; URL을 프레임을 통해서 보여준다.
    &apos;---------------------------------------------------
    Sub UrlFramePage(pUrlName, pUrl)
        dim outStr
        outStr = outStr &amp; &quot;&lt;html&gt;&quot; &amp; vbCrLf
        outStr = outStr &amp; &quot;&lt;head&gt;&quot; &amp; vbCrLf
        outStr = outStr &amp; &quot;&lt;title&gt;&quot; &amp; pUrlName &amp; &quot;&lt;/title&gt;&quot; &amp; vbCrLf
        outStr = outStr &amp; &quot;&lt;/head&gt;&quot; &amp; vbCrLf

        outStr = outStr &amp; &quot;&lt;frameset rows=&quot;&quot;0,*&quot;&quot; border=0&gt;&quot; &amp; vbCrLf
        outStr = outStr &amp; &quot;    &lt;frame src=&quot;&quot;about:blank&quot;&quot; name=blank marginwidth=0 marginheight=0 leftmargin=0 topmargin=0 noresize&gt;&quot; &amp; vbCrLf
        outStr = outStr &amp; &quot;    &lt;frame src=&quot;&quot;&quot;&amp;pUrl&amp;&quot;&quot;&quot; name=body  scrolling=auto marginwidth=0 marginheight=0 leftmargin=0 topmargin=0&gt;&quot; &amp; vbCrLf
        outStr = outStr &amp; &quot;&lt;/frameset&gt;&quot; &amp; vbCrLf
        outStr = outStr &amp; &quot;&lt;/html&gt;&quot; &amp; vbCrLf
        Response.Write outStr
        Response.End
    End Sub
    &apos;---------------------------------------------------
    &apos; 404 에러페이지 보여주는 함수
    &apos;---------------------------------------------------
    Sub ErrorPage_404(errorURL)
        Response.Write errorURL &amp; &quot; 이 페이지를 찾을 수 없습니다.&quot;
    End Sub

%&gt;
&lt;/xmp&gt;
&lt;p&gt;


&lt;/p&gt;

&lt;p&gt;DB 연결등에 해당하는 가장 기본적인 설명은 패스하겠다. -_-&lt;/p&gt;
&lt;pre class=code&gt;
strQueryString  = Request.ServerVariables(&quot;QUERY_STRING&quot;)
strServerName   = &quot;http://&quot;&amp;Request.ServerVariables(&quot;SERVER_NAME&quot;)&amp;&quot;/&quot;
strServerPort   = Request.ServerVariables(&quot;SERVER_PORT&quot;)
&lt;/pre&gt;

&lt;p&gt;
일단 가장 기본적인 정보인 서버명과 포트정보를 받아온다. 서버명은 현재 웹서버의 서버명이고
포트는 웹서버로 이용하는 포트이다. Request.ServerVariables(&quot;QUERY_STRING&quot;) 에는 에러정보를 넘겨준다.
&lt;font color=blue&gt;&quot;에러번호;에러URL&quot;&lt;/font&gt; 이런식의 구조로 되어있다.
&lt;/p&gt;

&lt;pre class=code&gt;
errorNum = (Split(strQueryString,&quot;;&quot;))(0)
errorURL = (Split(strQueryString,&quot;;&quot;))(1)
&lt;/pre&gt;
    
&lt;p&gt;Split 함수를 이용해서 errorNum(에러번호) 와 errorURL(에러난 URL)을 변수에 저장시킨다.    &lt;/p&gt;

    
&lt;pre class=code&gt;
if errorNum = &quot;404&quot; and right(errorURL,1) &lt;&gt; &quot;/&quot; then
&lt;/pre&gt;

&lt;p&gt;에러번호 404는 Page Not Found 이다. 즉 해당하는 페이지가 실제 서버에 없다는 의미이다.
위의 조건절을 해석하면 &quot;페이지가 없으면서 errorURL 뒤에 슬래쉬가 없을경우 실질적으로 프로그램이 시작한다&quot;
&lt;/p&gt;

&lt;pre class=code&gt;
url_name = replace(errorURL,strServerName,&quot;&quot;)
instr_url = InStr(url_name,&quot;?&quot;)

&apos; URL 뒤에 QueryString 가 있을 경우
if instr_url &gt; 0 then
    url_param = mid(url_name,instr_url+1, len(url_name)-instr_url)
    url_name = left(url_name,instr_url-1)
end if
&lt;/pre&gt;
        
        
&lt;p&gt;이 strServerName 변수는 사용자가 입력한 주소값이다. 즉 http://www.myhome.com/mungchung 이 값을 말한다.
이 주소에서  mungchung 이 값만 가져오고 이 값을 url_name변수에 할당한다.
&lt;/p&gt;

&lt;p&gt;만일 이 주소에 파라미터를 넘겨주고 싶다면?   http://www.myhome.com/mungchung?myparam=aaa
이런식으로 적을경우 자동적으로 IIS가 myparam=aaa 이걸 파라미터로 인식하지 않는다. 그렇기 때문에
수동으로 코딩해줘야한다. 일반적으로 물음표뒤부터는 파라미터로 인식하므로 물음표 뒤부터의 값을 파라미터보고
url_param 변수에 저장한다. &lt;/p&gt;




&lt;pre class=code&gt;
&apos; 테이블을 검사해서 등록된 주소인지 확인한다.
strSql = &quot;Select url_name, url_title, url From TB_URL Where url_name=&apos;&quot; &amp; url_name &amp; &quot;&apos;&quot;
Set rs = DBCon.Execute(strSql)
if rs.eof then
    &apos; 등록된 주소가 아니면 에러페이지 보여주는 함수 호출
    Call ErrorPage_404(errorURL)
else
    db_url_name = rs(0)
    db_url_title= rs(1)
    db_url      = rs(2)

    &apos; URL 뒤에 Query String가 있었다면 URL뒤에 붙여준다.
    if url_param &lt;&gt; &quot;&quot; then
        db_url = db_url &amp; &quot;?&quot; &amp; url_param
    end if

    &apos; 등록된 주소로 이동시킨다.
    Call UrlFramePage(db_url_name, db_url)
end if
&lt;/pre&gt;
        
&lt;p&gt;        
url_name를 가지고 DB에 값이있는지 검사한다. DB에 값이 없다면 정의하지않은 URL 이므로 ErrorPage_404 함수를 호출
해서 에러문구를 보여준다. 만일 DB에있다면 UrlFramePage 함수를 호출해서 URL에 해당하는 페이지를 보여준다.
&lt;/p&gt;

&lt;p&gt;
마지막으로 UrlFramePage 함수 설명이다. 이 함수를 보면 알겠지만 프레임을 뿌려준다.
빈페이지 하나와 실제주소에 해당하는 페이지 하나를 통합해서 보여주는 프레임이다.
&lt;/p&gt;




&lt;a class=name&gt;셋째. IIS 셋팅&lt;/a&gt;
&lt;p&gt;간단하다. 이미지보고 따라해라 -_-&lt;/p&gt;
&lt;p&gt;&lt;img src=/mianamssi/articles/img/error_redirect/01.gif&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=/mianamssi/articles/img/error_redirect/02.gif&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=/mianamssi/articles/img/error_redirect/03.gif&gt;&lt;/p&gt;

&lt;a class=name&gt;넷째. 테스트&lt;/a&gt;

&lt;p&gt;http://localhost/mungchung 라고 들어가보자. 나의 홈피가 아주 잘 보인다.
익스플로러 제목표시줄을 보면 mungchung라 적혀있다.&lt;/p&gt;
&lt;p&gt;&lt;img src=/mianamssi/articles/img/error_redirect/04.gif&gt;&lt;/p&gt;

&lt;p&gt;이번엔 DB에도 없고 폴더나 가상디렉토리로도 없는 주소로 이동하려고해보자.
http://localhost/mungchung1 이렇게 들어가려고 하면 위의 코딩에서 정의한 에러메시지가 뜬다.&lt;/p&gt;

&lt;p&gt;&lt;img src=/mianamssi/articles/img/error_redirect/05.gif&gt;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;
아주 간단하게 에러페이지를 이용해 웹 어플리케이션과 같은 주소 이용하는 방법을 알아봤다.
이런 방법을 이용하면 회원들의 홈페이지 주소를 짧게 하거나 커뮤니티 주소를 짧게 해주는데 유용하다.
주소를 간단하고 짧게 해주는 방법중엔 각 회원별로 가상디렉토리를 생성해주는 방식도 있는데
이건 ADSI를 이용하므로 이 방식보단 조금 더 복잡하다. 또한 회원별로 폴더를 생성해야 하기 때문에
나중에 관리하기가 힘들어질수도 있다. 그렇기 때문에 개인적으로는 이 방식을 선호한다&lt;/p&gt;

&lt;p&gt;좀 더 멋지게 만들고 싶다면. 한가지 처리를 더 해줘야한다.
예를 들자면 내 홈에 접속하기 위해서(그럴리는 없지만-_-) http://www.myhome.com/mungchung
라고 입력했는데 이미 mungchung 폴더를 생성해 뒀다면? IIS는 폴더가 있기 때문에 에러로 인식안해서
mungchung 폴더로 이동해버린다. 때문에 404_error_redirect.asp 페이지까지 오질 못한다.
그래서 URL을 생성할때 가상디렉토리나 폴더로 이미 있는 명칭일경우 생성하지 못하도록하는 오류처리를 해줘야한다.
(귀찮은 처리니 패스 -_-;;;)
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;오랜만에 이미지 캡쳐까지 뜨니 힘들다 -_-&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>VB로 WebBrowser 컨트롤의 HTML 제어</title>
      <id>http://www.mungchung.com/xe/4188</id>
      <published>2006-12-01T03:57:26+09:00</published>
      <updated>2010-12-30T14:51:41+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.mungchung.com/xe/4188"/>
      <link rel="replies" type="text/html" href="http://www.mungchung.com/xe/4188#comment"/>
      <author>
         <name>뭉충닷컴</name>
                  <uri>http://www.mungchung.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;style&gt;Body {font-size:12px;font-family:굴림} P {line-height:120%; margin-top:0; margin-bottom:0;}&lt;/style&gt;
&lt;p&gt;&amp;nbsp;간간히 질문 올라오는것 같아서 간략하게 정리했습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;WebBrowser 컨트롤을 이용해서 VB에서 웹페이지 보여줄때 그 웹페이지를 VB에서 
제어하는 몇가지 예제입니다.&lt;/p&gt;
&lt;p&gt;(이 WebBrowser 컨트롤 이용하려면 &amp;nbsp;Microsoft Internet Controls을 구성요소에서 
추가해주는것 잊지 마시고요)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;VB 코드 입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;table border=&quot;1&quot; cellspacing=&quot;0&quot; bgcolor=&quot;#F4F4F4&quot;&gt;
    &lt;tr&gt;
        &lt;td width=&quot;751&quot;&gt;
            &lt;p&gt;Private Sub Command1_Click()&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WebBrowser1.Navigate App.Path &amp;amp; &amp;quot;\test.html&amp;quot;&lt;/p&gt;
            &lt;p&gt;End Sub&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, 
            URL As Variant)&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;On Error GoTo WebBrowser1_DocumentComplete_Error&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&apos;// 첫번째 자바스크립트 내용 가져오기&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MsgBox WebBrowser1.Document.scripts.Item(0).innerHTML&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&apos;// 두번째 자바스크립트 내용 가져오기&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MsgBox WebBrowser1.Document.scripts.Item(1).innerHTML&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&apos;// id 값이 spanid 인것 가져옴&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MsgBox WebBrowser1.Document.getElementsByName(&amp;quot;spanid&amp;quot;)(0).innerHTML&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&apos;// 폼 속성들 가져오기 가져오기&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MsgBox WebBrowser1.Document.Forms(0).Name&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MsgBox WebBrowser1.Document.Forms(0).method&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&apos;// 폼 요소 가져오기 (자바스크립트에서 
            이용하듯이 사용)&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MsgBox WebBrowser1.Document.Forms(0).user_name.Value&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MsgBox WebBrowser1.Document.Forms(0).homepage.Value&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&apos;// 값 바꾸기&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WebBrowser1.Document.Forms(0).homepage.Value 
            = &amp;quot;&lt;a href=http://www.empas.com&amp;quot; target=_blank&gt;http://www.empas.com&amp;quot;&lt;/a&gt;&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim tmpObj As HTMLDocument&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set tmpObj = WebBrowser1.Document&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;On Error GoTo 0&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Exit Sub&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;WebBrowser1_DocumentComplete_Error:&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;End Sub&lt;/p&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다음은 html 내용입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;table border=&quot;1&quot; cellspacing=&quot;0&quot; bgcolor=&quot;#F4F4F4&quot;&gt;
    &lt;tr&gt;
        &lt;td width=&quot;751&quot;&gt;
            &lt;p&gt;&amp;lt;html&amp;gt; &lt;/p&gt;
            &lt;p&gt;&amp;lt;head&amp;gt;&amp;lt;/head&amp;gt; &lt;/p&gt;
            &lt;p&gt;&amp;lt;script language=&apos;javascript&apos;&amp;gt; &lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alert(&apos;첫번째 스크립트입니다.&apos;); &lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;self.close();&lt;/p&gt;
            &lt;p&gt;&amp;lt;/script&amp;gt; &lt;/p&gt;
            &lt;p&gt;&amp;lt;script language=&apos;javascript&apos;&amp;gt; &lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;alert(&apos;두번재 스크립트 입니다.&apos;); &lt;/p&gt;
            &lt;p&gt;&amp;lt;/script&amp;gt; &lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;&amp;lt;body&amp;gt;&lt;/p&gt;
            &lt;p&gt;&amp;lt;span id=spanid&amp;gt;하하하&amp;lt;/span&amp;gt;&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;&amp;lt;form name=f1 method=post&amp;gt;&lt;/p&gt;
            &lt;p&gt;&amp;lt;input type=text name=user_name value=&amp;quot;손민창&amp;quot;&amp;gt;&lt;/p&gt;
            &lt;p&gt;&amp;lt;input type=text name=homepage value=&amp;quot;&lt;a href=http://www.mungchung.com&amp;quot;&amp;gt; target=_blank&gt;http://www.mungchung.com&amp;quot;&amp;gt;&lt;/a&gt;&lt;/p&gt;
            &lt;p&gt;&amp;lt;/form&amp;gt;&lt;/p&gt;
            &lt;p&gt;&amp;lt;/body&amp;gt;&lt;/p&gt;
            &lt;p&gt;&amp;lt;/html&amp;gt; &lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&lt;/p&gt;
            &lt;p&gt;&amp;nbsp;&lt;/p&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;워낙 간단한 예제들이라 별다른 설명은 필요없을듯하네요...&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;VB 코드를 보면 대부분 WebBrowser1.Document 을 통해서 HTML 코드로 접근합니다.&lt;/p&gt;
&lt;p&gt;접근 하는 방식은 JavaScript랑 비슷합니다.(거의 똑같다고 봐야하나 -_-;;)&lt;/p&gt;
&lt;p&gt;이 WebBrowser1.Document가 자바스크립트로 나타내자면 document랑 똑같습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;예를 들자면 f1 폼에서 homepage의 값(value)를 자바스크립트로 값확인하려면&lt;/p&gt;
&lt;p&gt;alert(document.forms[0].homepage.value) 입니다. 이것 VB로 나타낸게&lt;/p&gt;
&lt;p&gt;WebBrowser1.Document.Forms(0).homepage.Value 입니다. 거의 유사하지요.. -_-;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그 외의 다른 몇가지 예제들도 자바스크립트로 접근한 방식처럼 VB로 접근하면 
됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;헌데 VB에서 WebBrowser1.Document 까지 적은후 점(.)을 찍으면 속성이나 이벤트등이 
보여야하는데&lt;/p&gt;
&lt;p&gt;나타나지가 않아서 어떤 속성과 이벤트들이 있는지 알수가 없습니다.&lt;/p&gt;
&lt;p&gt;이것을 알고자 한다면 아래처럼 하면 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;1. Microsoft HTML Object Library 을 참조로 추가한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;2. 아래 이미지와 같이 임시변수(tmpObj)를 만든다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img name=zb_target_resize style=&quot;cursor:hand&quot; onclick=window.open(this.src)  src=&quot;http://www.mungchung.com/mianamssi/img/zboard/img1[0][0][0][0].gif&quot; align=&quot;bottom&quot; width=&quot;365&quot; height=&quot;155&quot; border=&quot;0&quot; alt=&quot;img1.gif&quot;&gt;&lt;/p&gt;
 
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;3. 이렇게 하면 WebBrowser1.Document 다음에 점찍으면 속성과 이벤트들이 보입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;아시겠지만 위의 코드대로 하면 WebBrowser1.Document 객체를 tmpObj 객체로 할당하면&lt;/p&gt;
&lt;p&gt;tmpObj.Forms(0).homepage.Value ..이렇게 코딩해도 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>ASP 페이징 쉽게 처리하기</title>
      <id>http://www.mungchung.com/xe/4184</id>
      <published>2006-08-29T14:32:43+09:00</published>
      <updated>2011-03-29T10:23:55+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.mungchung.com/xe/4184"/>
      <link rel="replies" type="text/html" href="http://www.mungchung.com/xe/4184#comment"/>
      <author>
         <name>뭉충닷컴</name>
                  <uri>http://www.mungchung.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;/mianamssi/include/star-light/star-light.css&quot; type=&quot;text/css&quot;/&gt;

&lt;p&gt;게시물 페이징이 사용자한텐 상당히 편한 기능이지만 개발자한테는 귀찮고 괴로운 작업중 하나다.
페이징을 해보면 알겠지만 페이징 처리를 위해서 목록 페이지 곳곳에 이런 저런 처리를 해줘야한다.
단지 페이지 이동 링크들 넣을 뿐인데 그 작업량은 상당하다.
&lt;/p&gt;
&lt;p&gt;이런 개노다(?) 작업외에 무시할 수 없는 부분이 페이징시 사용되는 쿼리문이다. 일전에
&quot;프로그래밍 Tip&quot;란에 큰머리님의 페이징 테스트 자료를 올려두었는데, 그 게시물만 보더라도
페이징 관련 쿼리문이 여러가지 있다. (&lt;a href=http://www.mungchung.com/mianamssi/zboard/view.php?id=protip&amp;no=180 target=_blank&gt;페이징 테스트 자료로 가기&lt;/a&gt;)
&lt;/p&gt;
&lt;p&gt;이 테스트 자료를 보면 가장 빠른 페이징을 6번째 방법이였는데 솔직히 이 방법은 실무에서
사용하긴 좀 부족한 감이 있다. 실제 개발에선 테이블 하나만 가지고 페이징하진 않는다.
몇개씩 조인한 테이블의 데이타들을 페이징 하는것은 물론 심한 경우 10개이상의 테이블에서 조인한 데이타를
페이징 해야하는 경우도 있다. (이 10개이상 조인은 상당히 비추천이지만 어쩔수 없는 경우가 있다 -_-;;;)
&lt;/p&gt;
&lt;p&gt;거기다 또 다른 문제는 쿼리문에 Distinct, Group, Having..등등 절을 사용했을 경우 실제 기존 사용하던 페이징 쿼리를 사용하면
잘 안맞는 경우가 있다. 이 부분은 개발시에 생각보다 간과하게 쉬운데 꼼꼼히 살펴보면 페이징 되는것이 뭔가 이상함을
발견할 수 있을것이다. 무리하게 기존 페이징 코드 Copy &amp; Paste했다간 추후 낭패를 본다 -_-
이런 쿼리들을 실제로 보여줬으면 좋을텐데 아쉽게도 제대로 정리해두질 않았고 그런 쿼리들을 지금 만들자니 끔찍하다.
그러니 그냥 &apos;그런 경우도 있구나...&apos; 라고만 생각해라 -_-;;;

&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이번에 다룰 페이징 함수는 위와 같은 문제점을 한방에 해결해준다. 적용하기 쉽고, 코드양 현저하게 줄어들고, 어떤 쿼리라도
정확하게 페이징 해준다.(물론 100% 장담 못한다. -_- 그냥 허위광고라 생각해라 -_-)
&lt;/p&gt;
&lt;p&gt;단! 단점이 있다. 속도는 보장 못한다. 이 함수는 속도보다는 편리함에 중점을 둔것이다. 페이징 속도를 생명처럼 여긴다면
이 함수 적용하지 않는것이 좋다. 뭐..그렇다고 속도가 기존 페이징 쿼리보다 2배이상 현저하게 떨어진다거나 그렇진 않다.
단지 속도에 중점을 둔 쿼리가 아니라는 것이다. (실제 개발에 사용했을때도 페이징 속도때문에 문제된적은 한번도 없었다 -_-)
&lt;/p&gt;
&lt;p&gt;또 한가지 단점은 레코드 수가 1000000000(10억)이 넘는 게시물은 페이징 할 수 없다. 이렇게 제한을 둔 이유는 Top 쿼리문
특성 때문인데...이 함수 만들당시에 왜 10억개로 제한했는지 기억이 안난다 -_-;; 그 당시 무슨 이유때문에 이렇게 만들어 두었는데
당췌 기억이... -_-;; 대충..기억으론 Top에서 사용할수 있는 개수 제한이 있었던것 같은데 지금 좀더 높은 수로 테스트 해봐도 된다.
문제는 그 당시는 ms-sql 2000으로 테스트 했었고 지금 로컬에 설치되어있는것은 ms-sql 2005이다. 그래서 정확하게 비교가 좀 그렇다.
&lt;/p&gt;
&lt;p&gt;혹시 Top 절의 개수 제한이 있는지 도움말과 이런 저런 책을 잠깐 봤는데..음 찾을수가 없다. 
그냥 10억개로 제한해두고 사용하자! 알겠지만 10억개까지 있는 게시물은 평생 찾아보기 힘들고 만들기도 힘들다.
일전에 큰머리님의 페이징 자료 테스트 해본다고 100만개 레코드 생성하는데 하다 포기했다.
한 40만개까지인가 만든것으로 기억하는데 간단한 레코드인데도 생성시간이 대략 한시간정도 걸린것으로 기억한다 -_-;;;
그러니 10억개 레코드 테스트 해보려고 한다면 몇일간 컴퓨터 개고생 시켜야 할것이다.&lt;/p&gt;


&lt;p&gt;음..뭔가 서론이 상당히 긴듯한데 결론은 ...다시 읽어보니 왠지 이 함수의 단점들을 변명하는것 같군 -_-
아무튼 실제 개발에 적용해도 문제없는 함수이니 필요하면 가져다 사용하자!&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;아래는 페이징 안하고 모든 레코드 가져오는 코드이다.&lt;/p&gt;

&lt;pre class=code&gt;
&amp;lt;% OPTION EXPLICIT %&amp;gt;
&amp;lt;%
Dim DBCon : Set DBCon = Server.CreateObject(&quot;ADODB.Connection&quot;)
Dim strConn : strConn = &quot;&quot;
Dim strQry
Dim rs

strConn = strConn&amp;&quot;Provider=SQLOLEDB.1;Persist Security Info=True;&quot;
strConn = strConn&amp;&quot;Data Source=localhost;&quot;  &apos; Server Name
strConn = strConn&amp;&quot;User ID=sa;&quot;             &apos; User ID
strConn = strConn&amp;&quot;Password=;&quot;              &apos; User Password
strConn = strConn&amp;&quot;Initial Catalog=NorthWind;&quot;   &apos; DataBase
DBCon.Open strConn

strQry = &quot;select CompanyName from Customers&quot;
Set rs = DBCon.Execute(strQry)

Do While not rs.eof
    Response.Write rs(0) &amp; &quot;&amp;lt;hr&amp;gt;&quot;
    rs.MoveNext()
Loop
rs.Close
Set rs = nothing
%&amp;gt;
&lt;/pre&gt;

&lt;p&gt;이 코드에 페이징 처리 구문을 넣어보자&lt;/p&gt;
&lt;pre class=code&gt;
&amp;lt;% OPTION EXPLICIT %&amp;gt;
&amp;lt;!--#include file=&quot;asp_page_function.asp&quot;--&amp;gt;
&amp;lt;%
Dim DBCon : Set DBCon = Server.CreateObject(&quot;ADODB.Connection&quot;)
Dim strConn : strConn = &quot;&quot;
Dim strQry
Dim rs
&lt;font color=red&gt;Dim req_curPage : req_curPage = Request(&quot;curPage&quot;)&lt;/font&gt;

strConn = strConn&amp;&quot;Provider=SQLOLEDB.1;Persist Security Info=True;&quot;
strConn = strConn&amp;&quot;Data Source=localhost;&quot;  &apos; Server Name
strConn = strConn&amp;&quot;User ID=sa;&quot;             &apos; User ID
strConn = strConn&amp;&quot;Password=;&quot;              &apos; User Password
strConn = strConn&amp;&quot;Initial Catalog=NorthWind;&quot;   &apos; DataBase
DBCon.Open strConn

strQry = &quot;select CompanyName from Customers&quot;
&lt;font color=red&gt;Set rs = ExecutePage(strQry,req_curPage)&lt;/font&gt;

Do While not rs.eof
    Response.Write rs(0) &amp; &quot;&amp;lt;hr&amp;gt;&quot;
    rs.MoveNext()
Loop
rs.Close
Set rs = nothing

&apos; 페이지 이동 부분 뿌려준다.
&lt;font color=red&gt;Response.Write ShowPageBar(req_curPage,&quot;&quot;,&quot;&quot;,&quot;&quot;)&lt;/font&gt;
%&amp;gt;
&lt;/pre&gt;

&lt;p&gt;단지, 강조된 부분만 처리해주면 바로 페이징이 된다! 몇번을 야려봐도 정말 간단하다(나만 간단한가 -_-;;)&lt;/p&gt;
&lt;p&gt;하나씩 살펴보면 일단 보여줄 페이지 번호를 Request로 받아온다.&lt;/p&gt;
&lt;pre class=code&gt;
&lt;pre class=asp&gt; 
Dim req_curPage : req_curPage = Request(&quot;curPage&quot;)
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;그래서 그 보여줄 페이지 번호와 쿼리문을 ExecutePage 함수에 인자로 던져준다.&lt;/p&gt;
&lt;pre class=code&gt;
&lt;pre class=asp&gt; 
Set rs = ExecutePage(strQry,req_curPage)
&lt;/pre&gt;&lt;/pre&gt;
&lt;p&gt;그런후 페이지 이동바 함수를 호출해서 뿌려주면 끝이다.&lt;/p&gt;
&lt;pre class=code&gt;
&lt;pre class=asp&gt; 
Response.Write ShowPageBar(req_curPage,&quot;&quot;,&quot;&quot;,&quot;&quot;)
&lt;/pre&gt;&lt;/pre&gt;


&lt;p&gt;만약 뿌려질 목록수를 10개에서 20개 혹은 30개로 조절하고 싶다거나 페이지 이동바의 모양을 변경하고 싶다거나..
등등 미묘한 설정을 건드리고 싶다면 asp_page_function.asp 이 파일 열어서 수정하면된다.
나름대로 주석 여기저기 달아두었으니 수정하는데 그리 큰 어려움은 없을꺼라 본다.
아! 잠시 깜빡하고 넘어갈뻔했는데 실제로 이 페이징 함수 적용하려면 asp_page_function.asp 파일 수정해 줘야한다.
거기서 DB연결 객체의 Execute 이용하는데.. 개발자마다 DB연결객체 처리 방식이 틀리기 때문에 그 부분은
수정해 줘야한다. 그러니 소스코드 다운받고 실행하고선 곧바로 &apos;이거 왜 안되지?&apos;라고만 생각하지 말고 
자신의 설정에 맞게 코드들 좀 수정해 줘야한다.&lt;/p&gt;


&lt;p&gt;마지막으로 asp_page_function.asp의 코드를 보자 이 페이징 처리의 핵심 로직이 들어가있다 -_-&lt;/p&gt;

&lt;pre class=code&gt;
&lt;pre class=asp&gt;
&amp;lt;%
&apos;#################################################################################
&apos;# 페이징 관련 함수
&apos;#################################################################################

&apos; 페이징시 필요한 전역변수 2개
Dim G_PAGE_SIZE : G_PAGE_SIZE = 10  &apos; 뿌려질 레코드 개수
Dim G_TOTAL_RECORD                  &apos; 전체 레코드 수


&apos;/* 쿼리문 + 페이징 */
Public Function ExecutePage(ByVal pSql, ByVal pPage)
    Dim rs : Set rs = Server.CreateObject(&quot;ADODB.RecordSet&quot;)
    Dim strSQL
    Dim nPage
    Dim cut, l_sql, r_sql
    
    If pPage = &quot;&quot; or isNull(pPage) Then pPage = 1

    pSql = UCase(pSql)                  &apos; 대문자로 변환  
    pSql = Replace(pSql, vbTab, &quot; &quot;)    &apos; 쿼리문의 Tab은 Space로 
    pSql = Replace(pSql, vbCr, &quot; &quot;)     &apos; 쿼리문의 개행은 Space로
    
    cut = InStr(1, pSql, &quot; TOP &quot;)
    &apos; top 절이 없으면 order by에서 오류 - top절 있는지 검사
    If cut = 0 Then
        cut = InStr(1, pSql, &quot; DISTINCT &quot;)
        If cut &amp;gt; 0 Then
            &apos; distinct 가 있을 경우
            cut = cut + 8
            l_sql = Left(pSql, cut)
            r_sql = Right(pSql, Len(pSql) - cut - 1)
            
            pSql = l_sql &amp; &quot; TOP 1000000000 &quot; &amp; r_sql
        Else
            &apos; distinct 가 없을 경우
            cut = InStr(1, pSql, &quot;SELECT &quot;)
            If cut &amp;gt; 0 Then
                cut = cut + 5
                l_sql = Left(pSql, cut)
                r_sql = Right(pSql, Len(pSql) - cut - 1)
                
                pSql = l_sql &amp; &quot; TOP 1000000000 &quot; &amp; r_sql
            End If
        End If
    End If
    
    nPage = pPage * CLng(G_PAGE_SIZE)
    strSQL = &quot;Select TOP &quot; &amp; CStr(nPage) &amp; &quot; * From (&quot; &amp; pSql &amp; &quot;) AS _TEMP_PAGE_TABLE&quot;
    
    G_TOTAL_RECORD = ExecuteCount(pSql)     &apos; 쿼리문의 전체 레코드 수 구함
        
    rs.CursorType = 1
    rs.PageSize = G_PAGE_SIZE
    rs.Open strSQL, DBCon
    
    If Not (rs.EOF Or rs.BOF) Then rs.AbsolutePage = pPage
    
    Set ExecutePage = rs
End Function

&apos;/* 쿼리문을 주면 그 쿼리문의 레코드 수를 반환 */
Public Function ExecuteCount(ByVal pSql)
    Dim rs : Set rs = Server.CreateObject(&quot;ADODB.RecordSet&quot;)

    pSql = &quot;Select Count(*) From (&quot; &amp; pSql &amp; &quot;) AS _TEMP_PAGE_TABLE_CNT&quot;
    Set rs = DBCon.Execute(pSql)
    
    ExecuteCount = CLng(rs(0))
    rs.Close
    Set rs = nothing
End Function

&apos;/* 페이징시 전체 페이지수 계산 */
Function GetPageCount(ByVal pTotalRecord)
    Dim retVal
    
    pTotalRecord = CLng(pTotalRecord)
    retVal = Fix(pTotalRecord / G_PAGE_SIZE)
    If (pTotalRecord Mod G_PAGE_SIZE) &amp;gt; 0 Then
        retVal = retVal + 1
    End If
    GetPageCount = CLng(retVal)
End Function

&apos;/* 페이지 네비게이션을 뿌려주는 함수 */
Public Function ShowPageBar(ByVal pCurPage, ByVal pPreImg, ByVal pNextImg, ByVal param)
    Dim nPREV
    Dim nCUR
    Dim nNEXT
    Dim i
    Dim nPageCount
    Dim retVal
    Dim strLink
    Dim pageKubun

    If pCurPage = &quot;&quot; or isNull(pCurPage) Then pCurPage = 1
    
    nPageCount = GetPageCount(G_TOTAL_RECORD)
    
    If pPreImg = &quot;&quot; Then
        pPreImg = &quot;[이전]&quot;
    Else
        pPreImg = &quot;&amp;lt;img src=&apos;&quot; &amp; pPreImg &amp; &quot;&apos; border=0 align=absmiddle&amp;gt;&quot;
    End If
    
    If pNextImg = &quot;&quot; Then
        pNextImg = &quot;[다음]&quot;
    Else
        pNextImg = &quot;&amp;lt;img src=&apos;&quot; &amp; pNextImg &amp; &quot;&apos; border=0 align=absmiddle&amp;gt;&quot;
    End If
    
    nPREV = (Fix((pCurPage - 1) / 10) - 1) * 10 + 1
    nCUR = (Fix((pCurPage - 1) / 10)) * 10 + 1
    nNEXT = (Fix((pCurPage - 1) / 10) + 1) * 10 + 1

    &apos; [이전] 페이지 조합
    If nPREV &amp;gt; 0 Then
        strLink = &quot;?curPage=&quot; &amp; nPREV &amp; param
        retVal = &quot;&amp;lt;a href=&quot;&quot;&quot; &amp; strLink &amp; &quot;&quot;&quot;&amp;gt;&quot; &amp; pPreImg &amp; &quot;&amp;lt;/a&amp;gt;&amp;nbsp;&quot;
    Else
        retVal = &quot;&quot; &amp; pPreImg &amp; &quot;&amp;nbsp;&quot;
    End If
    i = 1
    Do While i &amp;lt; 11 And nCUR &amp;lt;= nPageCount
        If nCUR = nPageCount Or i = 10 Then
            pageKubun = &quot; &quot;
        Else
            pageKubun = &quot; . &quot;
        End If
        
        If CInt(pCurPage) = CInt(nCUR) Then
            retVal = retVal &amp; &quot;&amp;lt;font color=#FF6700 size=3&amp;gt;&amp;lt;b&amp;gt;&quot; &amp; nCUR &amp; &quot;&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;&quot; &amp; pageKubun
        Else
            strLink = &quot;?curPage=&quot; &amp; nCUR &amp; param
            retVal = retVal &amp; &quot;&amp;lt;a href=&quot;&quot;&quot; &amp; strLink &amp; &quot;&quot;&quot;&amp;gt;&quot; &amp; nCUR &amp; &quot;&amp;lt;/a&amp;gt;&quot; &amp; pageKubun
        End If
        nCUR = nCUR + 1
        i = i + 1
    Loop
    &apos; [다음] 페이지 조합 
    If nNEXT &amp;lt;= nPageCount Then
        strLink = &quot;?curPage=&quot; &amp; nNEXT &amp; param
        retVal = retVal &amp; &quot;&amp;nbsp;&amp;lt;a href=&quot;&quot;&quot; &amp; strLink &amp; &quot;&quot;&quot;&amp;gt;&quot; &amp; pNextImg &amp; &quot;&amp;lt;/a&amp;gt;&quot;
    Else
        retVal = retVal &amp; pNextImg &amp; &quot;&quot;
    End If
    
    ShowPageBar = retVal
End Function
%&amp;gt;
&lt;/pre&gt;&lt;/pre&gt;
&lt;p&gt;(이상하게 asp_page_functioh.asp 의 소스코드가 star-light 적용했더니 들여쓰기가 잘 안맞는다. -_- 실제 소스코드는 제대로 되어있으니
실제 코드 다운받아 보면된다.)&lt;/p&gt;

&lt;p&gt;함수 총 4개에 전역변수 2개다. &lt;/p&gt;

&lt;p&gt;전역변수 2개는 &quot;보여줄 게시물 갯수 지정&quot;, &quot;전체 레코드 수&quot; 이다.
함수 4개에서 이 전역변수 2개를 이용해서 데이타를 만들어 내기 때문에 없애거나 변수명 수정하면 안된다.
만일 수정하려면 함수안에 있는 전역변수 명까지 다 수정해주자. 
이렇게 함수간의 통신을 위해서 전역변수를 이용하는 방법은 그다지 좋은 방법은 아닌데..내가 기존에 사용하고 있던
모듈에서 페이징 부분만 떼어오다보니 이렇게 바꿔버리게 되었다. 원랜 소스는 전역변수들이 전부 클래스의 멤버 변수로 선언되서 사용되는데
공개용으로 함수를 만들다보니 클래스를 이용하는 방법이 적당치 않은듯해서...어찌 어찌 하다보니 이렇게 되었다 -_-;;;
&lt;/p&gt;
&lt;p&gt;함수 4개는 &quot;페이징 처리 함수&quot;,&quot;전체 레코드수 가져오는 함수&quot;,&quot;페이지 갯수 계산하는 함수&quot;,&quot;페이지 이동바 만들어주는 함수&quot; 이렇게 4개인데
그 중에서 첫번째 함수의 마지막 함수만 주의해서 보면 된다. 
첫번째 함수는 쿼리문과 페이지 번호를 받으면 그 페이지에 해당하는 게시물만 가져오는 함수다. 가장 중요한 함수다. 자세한 설명은 없다. 그냥 야리는거다. -_-
마지막 함수는 페이지이동바를 만들어주는데...역시나 보면 안다. -_-
&lt;/p&gt;
&lt;p&gt;오늘도 이렇게 날림강좌 하나 완성이다. 후훗 뿌뜻하다.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;p/s 이번 강좌 적으면서 내 강좌에 대한 내 스스로 느낀점&lt;br&gt;
1. 헛소리가 많다.&lt;br&gt;
2. 지식이 얕고 귀찮아서 자세한 정보 잘 제공 안한다.&lt;br&gt;
3. 소스코드 전체를 그냥 보여준다.&lt;br&gt;
4. 그 소스코드 설명 안하고 무조건 야리라고만 한다.&lt;br&gt;
5. 그림이 없어서 이해가 힘들다.&lt;br&gt;
5. -_-  &lt;ㅡ 요게 너무 많다 -_-&lt;br&gt;
&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>두개의 비슷한 DB를 비교해서 변경된 부분 찾아내기</title>
      <id>http://www.mungchung.com/xe/4182</id>
      <published>2006-05-03T23:17:49+09:00</published>
      <updated>2011-07-19T14:25:52+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.mungchung.com/xe/4182"/>
      <link rel="replies" type="text/html" href="http://www.mungchung.com/xe/4182#comment"/>
      <author>
         <name>뭉충닷컴</name>
                  <uri>http://www.mungchung.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;link rel=&quot;stylesheet&quot; href=&quot;/mianamssi/include/star-light/star-light.css&quot; type=&quot;text/css&quot;/&gt;

&lt;p&gt;이미 구축된 사이트 리뉴얼을 할때 커다른 이슈사향중 하나는 DB이관 작업이다.
이 DB이관이 어려운 이유는 리뉴얼시 대부분 DB 의 테이블 구조, 항목등이 변경되기 때문이다.&lt;/p&gt;

&lt;p&gt;아예 새로 DB를 구축하고 새로운 구조로 만든후 기존 데이타를 포팅한다면 포팅시에만 주의하면 된다.
근데 새로운 구조가 아닌 기존 DB구조를 그대로 유지한채 몇개의 필드, 몇개의 테이블이 삭제되는 형태로
리뉴얼이 진행된다면 나중에 DB이관 작업시에 하나씩 일일이 소소하게 살펴보느라 힘들다.&lt;/p&gt;

&lt;p&gt;물론 꼼꼼한 개발자라면 변경사항을 어딘가에 기록해 두겠지만 지속적으로 변경된 사항을 관리하기란 쉽지 않다.
나도 꼼곰한 성격은 아니지만 나중에 피보기 싫어서 변경된 부분들은 어딘가에 기록을 해두는데 처음에나 열심히
적고 나중에는 귀찮아서 대충 적는다. -_- 이러다보니 리뉴얼 끝난후 DB이관하려 할때 괴로워진다.&lt;/p&gt;

&lt;p&gt;그래서 이런 괴로움과 귀찮음을 없애고자 sql문 몇가지 만들었다. 뭐 별건 없다. 단지 원본DB와 변경DB의 테이블들을
비교해서 변경된 사항을 찾아내는것 뿐이다. 뭐..좀 시간 되면 프로시저로 만들어서 원클릭만으로
변경된 DB로 샥~ 하고 바뀌게 했음 좋겠지만 ...요게 좀 위험할것 같다. (귀찮기도 하고 -_-..)&lt;/p&gt;


&lt;p&gt;음..원랜 NorthWind DB를 이용해서 원본DB만들고 변경DB 만들어서 sql문 실행하면 삭제된 테이블 변경된 필드..등등
이미지 캡쳐까지 해서 이뿌게 보여주려 했는데.. 귀찮다 -_-&lt;/p&gt;

&lt;p&gt;그냥 알아서 NorthWind DB 이용해서 DB하나더 만들고 이리저리 테이블 삭제해보고 필드 변경해보고 해서 스스로
해보길 바란다. (참고로 이미 알고들 있겠지만 NorthWind 테이블 장난쳐서 망가졌다고 해도 
C:\Program Files\Microsoft SQL Server\MSSQL\Install 폴더 안의 instnwnd.sql 이용해서 복구할수 있으니 걱정말고
막 이용해도 된다.)&lt;/p&gt;



&lt;p&gt;일단! 아래 sql문을 이용하기 전에 각 DB에 view를 하나 만들어 줘야한다. 뭐하는 뷰냐면 현재 DB내의 테이블/뷰/프로시저의
정보를 가져오는 뷰인데...몇년전에 웹으로 테이블 정의서 만들겠다고 난리치면서 만들어둔 뷰이다.
(이 뷰는 꽤 유용한것 같다.. 스스로 잘 사용하고 있다 -_-) 아래는 뷰 구조이다.&lt;/p&gt;
&lt;pre class=code&gt;
&lt;pre class=tsql&gt;
CREATE VIEW dbo.viewTableInfo AS
select
	distinct
	A.name as	[tbl_id]
	,B.name as	[col_id]
	,C.name as	[data_type]
	,B.length AS	[len]
	,E.text as	[def_val]
	,B.isnullable as	[all_null]
	,B.autoval as	[a_n]
	,D.colid as	[p_k]
	,A.xtype
	,A.id
	,B.colorder	[col_ord]
from
	sysobjects as A
	inner join syscolumns B on A.id=B.id
	inner join systypes as C on C.xusertype=B.xusertype
	left join sysindexkeys as D	on B.id=D.id and B.colid=D.colid
	left join syscomments as E	on E.id=B.cdefault
where
	A.xtype in (&apos;U&apos;,&apos;V&apos;,&apos;P&apos;)
	and A.status &gt;= 0
	and left(A.name,4) &lt;&gt; &apos;viewTableInfo&apos;
&lt;/pre&gt;&lt;/pre&gt;
&lt;p&gt;별거 없다. 귀찮음을 불구하고 설명하자면 아래와 같다.&lt;/p&gt;
&lt;pre class=code&gt;
tbl_id : 테이블명
col_id : 컬럼명(필드명)
data_type : 데이타 타입
len : 데이타 길이
def_val : 기본값
all_null : 널 허용 여부
a_n : 자동증가 여부
p_k : 인덱스 
xtype : U(테이블), V(뷰), P(프로시저)
id : 뭐더라 -_-.. 아마 시스템 내무적으로 인식하는 컬럼 키값일것이다.
colorder : 컬럼 순번
&lt;/pre&gt;

&lt;p&gt;다시한번 말하지만 이 뷰를 변경DB, 원본DB에 각각 생성해 줘야한다. 왜냐면 비교할때 이 뷰를 읽어서 비교하기 때문이다.
아..그리고 용어를 정리하자면 &lt;font color=blue&gt;&lt;b&gt;원본DB (OriginalDB), 변경DB (ChangeDB)&lt;/b&gt;&lt;/font&gt; 이렇게되니 sql문 읽을때 염두해두면된다.&lt;/p&gt;

&lt;p&gt;자! 실질적으로 비교시에 사용할 쿼리이다. 설명 없다. 그냥 본다. 휘리릭~&lt;/p&gt;


&lt;pre class=code&gt;
&lt;pre class=tsql&gt;
/***** 신규 테이블 */
select
    distinct
    a.tbl_id
from
    ChangeDB..viewTableInfo a
where
    a.xtype=&apos;U&apos;
    and a.tbl_id not in (select distinct b.tbl_id from OriginalDB..viewTableInfo b)


/***** 신규 필드 */
select
    a.*
from
    viewTableInfo a
    left join OriginalDB..viewTableInfo b on a.tbl_id=b.tbl_id and a.col_id=b.col_id
where
    a.xtype =&apos;U&apos;
    and b.col_id is null
    and a.tbl_id in (select distinct c.tbl_id from OriginalDB..viewTableInfo c)
order by a.tbl_id, a.col_ord


/***** 변경된 필드 */
select
    a.tbl_id, a.col_id, a.data_type, a.len, a.def_val, a.all_null, a.a_n, a.p_k,
    b.tbl_id, b.col_id, b.data_type, b.len, b.def_val, b.all_null, b.a_n, b.p_k
from
    viewTableInfo a
    left join OriginalDB..viewTableInfo b on a.tbl_id=b.tbl_id and a.col_id=b.col_id
where
    a.xtype =&apos;U&apos;
    and b.col_id is not null
    and (a.len&lt;&gt;b.len 
            or a.data_type&lt;&gt;b.data_type 
            or a.def_val&lt;&gt;b.def_val 
            or a.all_null&lt;&gt;b.all_null 
            or a.p_k&lt;&gt;b.p_k 
            or left(isNull(a.a_n,0),2)&lt;&gt;left(isNull(b.a_n,0),2)
         )
order by a.tbl_id, a.col_ord



/***** 삭제된 테이블 */
select
    distinct
    a.tbl_id
from
    OriginalDB..viewTableInfo a
where
    a.xtype=&apos;U&apos;
    and a.tbl_id not in (select distinct b.tbl_id from viewTableInfo b)
   

/***** 삭제된 필드 */ 
select
    a.tbl_id
    , a.col_id
from
    OriginalDB..viewTableInfo a
    left join ChangeDB..viewTableInfo c on a.tbl_id=c.tbl_id and a.col_id=c.col_id
where
    a.xtype=&apos;U&apos;
    and c.col_id is null
    and a.tbl_id in (select distinct b.tbl_id from viewTableInfo b)
order by a.tbl_id
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;(후훗.. 이번 글에는 자동으로 코드컬러링 해주는 star-light 이용했다.)&lt;/p&gt;
&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>ASP에서 Class 를 이용해보자</title>
      <id>http://www.mungchung.com/xe/4180</id>
      <published>2006-02-26T12:07:29+09:00</published>
      <updated>2010-12-30T14:51:41+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.mungchung.com/xe/4180"/>
      <link rel="replies" type="text/html" href="http://www.mungchung.com/xe/4180#comment"/>
      <author>
         <name>뭉충닷컴</name>
                  <uri>http://www.mungchung.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;오랜만에 도움안되는 강좌하나 쓴다. asp로 class 이용하는 방법이다.
asp의 class 기능은 상당히 미약해서 java나 닷넷처럼 간지 좔좔 흐르도록 사용할수가 없다.
그냥 어설프게 흉내내는 정도만 가능한데 이 정도만 해도 여러가지 장점을 가지게 된다.&lt;/p&gt;

&lt;p&gt;클래스의 장점은...직접 사용해보면 안다. -_- 처음엔 귀찮지만 사용해보면 편해서 좋다는것을 안다.
보통 책을 사면 어떤 특정기능을 설명하면서 장,단점을 설명해놓는데 사실 그런 부분을 실제로
사용하기 전까지는 좋은지도 모른다. 단지 멍하니 읽고 지나치는 부분들이다. 
(실은 클래스의 장,단점 찾아적기 귀찮아서 안적는거다 -_- asp의 클래스에 대한 책이 거의 없다보니 -_-..)&lt;/p&gt;

&lt;p&gt;장점은 그냥 넘어가고..클래스의 확실한 단점으론 속도 문제를 들 수 있다.
아무래도 스크립트 언어 특징상 한 페이지에 코드양이 많으면 그만큼 속도가 늘어나는데
클래스를 이용하면 기존 asp코딩방식보단 코딩량이 몇배로 늘어난다. 그래서 페이지 실행하는 양이 늘어나서
속도문제가 생긴다. &lt;/p&gt;

&lt;p&gt;근데 이 문제는 단점중 하나긴 하지만 그렇게 큰 부하를 걸리게 하는 것은 아니다.
페이지의 속도문제를 그렇게 강조하고 싶다면 asp에서 인클루드를 사용하지 말아야하고 함수 또한 이용하지 말아야한다.
즉 가장 스크립트적인 asp 코딩을 하면 된다. 하지만 많은 개발자들은 이런식의 코딩은 안한다. 왜냐면 경험상
이렇게 코딩하다간 나중에 고칠때 개고생한다는걸 알기 때문이다. 그래서 속도좀 떨어지더라도  DB 연결 부분, 공통 함수 부분들은
 인클루드 해놓고선 코딩한다. 이런 정도만 해도 페이지 코딩시 상당량 개노가다가 줄어들기 때문이다.&lt;/p&gt;

&lt;p&gt;속도가 안나온다면 DB 이용시에 데이타 가져오는 속도가 느려서 그런것이니 DB 튜닝쪽을 생각해보는게 
더 좋은 해결책을 찾을 수 있을 것이다.&lt;/p&gt;

&lt;p&gt;말하다가 엉뚱한곳으로 흘렀는데...정리하자면 클래스를 이용하면 속도가 조금 아주 쪼금 절대 개발자가 알수 없을 정도의
속도가 느려짐이 있을수 있겠지만 개발/개선시의 편리성을 생각해본다면 그까이것 속도는 무시해도 될만한 정도이다.&lt;/p&gt;

&lt;p&gt;참! 강좌보기전에! 샘플 코드는 첨부파일 다운 받으시오!&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;#a&quot;&gt;1. 기존 ASP 코딩 방식&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;#b&quot;&gt;2. 클래스 이용&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;#c&quot;&gt;3. 클래스 이용 확장&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;






&lt;p&gt;&lt;a name=&quot;a&quot; class=&quot;name&quot;&gt;1. 기존 ASP 코딩 방식&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;클래스를 알기전에 일단 기존 asp 코딩방식부터 보자. 아래 코드는 기존 asp 코딩 방식이다.&lt;/p&gt;


&lt;pre class=code&gt;
    &lt;font color=green&gt;&apos;// 고전 ASP 코딩 방식&lt;/font&gt;
    Dim DBCon : Set DBCon = Server.CreateObject(&quot;ADODB.Connection&quot;)
    Dim rs : Set rs = Server.CreateObject(&quot;ADODB.RecordSet&quot;)
    Dim strConn
    Dim db_CustomerID
    Dim db_CompanyName
    Dim db_Phone
    Dim id
    
    &lt;font color=green&gt;&apos; DB 연결&lt;/font&gt;
    strConn = strConn&amp;&quot;Provider=SQLOLEDB.1;Persist Security Info=True;&quot;
    strConn = strConn&amp;&quot;Data Source=;&quot;   &lt;font color=green&gt;&apos; Server Name&lt;/font&gt;
    strConn = strConn&amp;&quot;User ID=sa;&quot;     &lt;font color=green&gt;&apos; User ID&lt;/font&gt;
    strConn = strConn&amp;&quot;Password=;&quot;      &lt;font color=green&gt;&apos; User Password&lt;/font&gt;
    strConn = strConn&amp;&quot;Initial Catalog=NorthWind;&quot; &lt;font color=green&gt;&apos; DataBase&lt;/font&gt;
    DBCon.Open strConn  
    
    id = &quot;AROUT&quot;
    
    strSql = &quot;select CustomerID,CompanyName,Phone from Customers Where CustomerID=&apos;&quot; &amp; id &amp; &quot;&apos;&quot;
    Set rs = DBCon.Execute(strSql)
    if not rs.eof then
        db_CustomerID  = rs(0)
        db_CompanyName = rs(1)
        db_Phone       = rs(2)
    end if
    
    &lt;font color=green&gt;&apos; 자원해제&lt;/font&gt;
    rs.Close
    DBCon.Close
    Set rs = nothing
    Set DBCon = nothing
&lt;/pre&gt;    
    


&lt;p&gt;asp 입문이 아니라면 아주 쉽게 이해할 수 있는 구문이니 코드 설명은 안하겠다 -_-..
쇼핑몰을 하나 개발한다고 가정하자. 쇼핑몰을 만들다 보면 사용자의 개인 정보를 가져오는 페이지들이 상당히 많다.
보통 개발자들은 위와같은 코드를 사용자정보 가져오는 페이지에서 코딩한다. 사용자 정보를 필요로 하는 페이지가 100개라면
100 곳에서 같은 코딩을 한다. 헌데 만약 테이블의 필드명(혹은 속성)이 변경되었다면? 그야말로 x 되는거다.&lt;/p&gt;
100곳 열어서 존내 수정해 줘야하는거다. 

&lt;p&gt;그나마 이런 상황은 괜찮은 편이다. 개발자가 5명이라서 각각 개발하는 스타일도 틀려서 사용자 정보 가져오는 코딩 스타일로 틀리다.
물론 개발하기 전에 개발표준정의안에서 맞추는 경우도 있지만 실제론 잘 안맞는 경우가 대부분이다.
이런 상황에서 개발자 한명이 다른 사람이 코딩한 소스도 고칠일이 생기면 정말 괴롭게 된다.
가져오는 정보는 동일한 정보인데 페이지마다 코딩 스타일도 틀리고 가져오는 쿼리도 틀리다면 ... -_- 욕이 절로 흥이나서 나온다.&lt;/p&gt;



&lt;p&gt;&lt;a name=&quot;b&quot; class=&quot;name&quot;&gt;2. 클래스 이용&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;그래서 동일하게 가져오는 정보는 클래스로 만드는것도 괜찮은 해결책중 하나이다. 
개발자들은 단지 클래스의 몇가지 메서드들만 이용하면 손쉽게 사용자 정보를 얻어올 수 있다.
아래 코드는 클래스를 통해서 고객정보를 받아오는 구문이다.&lt;/p&gt;



&lt;pre class=code&gt;
    &lt;font color=green&gt;&apos;// Class를 이용한 ASP&lt;/font&gt;
    Class clsCustomer
        &lt;font color=green&gt;&apos;// 멤버 변수&lt;/font&gt;
        private m_CustomerID
        private m_CompanyName
        private m_Phone
        private DBCon
        
        &lt;font color=green&gt;&apos;// Get 속성&lt;/font&gt;
        public property get CustomerID()
            CustomerID = m_CustomerID
        end property

        public property get CompanyName()
            CompanyName = m_CompanyName
        end property
        
        public property get Phone()
            Phone = m_Phone
        end property
        
        &lt;font color=green&gt;&apos; 클래스 초기화&lt;/font&gt;
        Private Sub Class_Initialize 
            Dim strConn
            strConn = strConn&amp;&quot;Provider=SQLOLEDB.1;Persist Security Info=True;&quot;
            strConn = strConn&amp;&quot;Data Source=;&quot;   &lt;font color=green&gt;&apos; Server Name&lt;/font&gt;
            strConn = strConn&amp;&quot;User ID=sa;&quot;     &lt;font color=green&gt;&apos; User ID&lt;/font&gt;
            strConn = strConn&amp;&quot;Password=;&quot;      &lt;font color=green&gt;&apos; User Password&lt;/font&gt;
            strConn = strConn&amp;&quot;Initial Catalog=NorthWind;&quot; &lt;font color=green&gt;&apos; DataBase&lt;/font&gt;
            
            Set DBCon = Server.CreateObject(&quot;ADODB.Connection&quot;)
            DBCon.Open strConn    
        End Sub
        &lt;font color=green&gt;&apos; 클래스 종료&lt;/font&gt;
        Private Sub Class_Terminate   &apos; Setup Terminate event.
            if DBCon.State = 2 then DBCon.Close
            Set DBCon = Nothing
        End Sub
        
        &lt;font color=green&gt;&apos; CustomerID를 인자로 주면 Customer의 정보를 반환함&lt;/font&gt;
        Public Sub init(id)
            Dim rs : Set rs = Server.CreateObject(&quot;ADODB.RecordSet&quot;)
            Dim strSql
            
            strSql = &quot;select CustomerID,CompanyName,Phone from Customers Where CustomerID=&apos;&quot; &amp; id &amp; &quot;&apos;&quot;
            Set rs = DBCon.Execute(strSql)
            if not rs.eof then
                m_CustomerID  = rs(0)
                m_CompanyName = rs(1)
                m_Phone       = rs(2)
            end if
            rs.Close
            Set rs = nothing
        End Sub
    End Class
&lt;/pre&gt;    
    


&lt;p&gt;위의 클래스는 가장 단순한 구조의 클래스이다. 
Class_Initialize는 클래스 초기화로써 클래서 생성시 항상 실행되는 구문이다. asp 클래스 내장함수이다.
선언해도 되고 안해도 된다. 이 함수엔 DB 연결 구문을 넣어두었다.
Class_Terminate는 클래스 종료시 실행되는 함수이다. 역시 asp 클래스 내장함수이다. 여기선 DB 연결 닫는 구문을 넣어두었다.
그 외에 CustomerID / CompanyName / Phone 정보에 대한 Get 속성과 init 프로시저를 추가해 두었다.&lt;/p&gt;

&lt;p&gt;이런식으로 클래스를 만들어 두었으면 사용시에는 단지 아래처럼 하기만 하면 된다.&lt;/p&gt;

&lt;pre class=code&gt;
    Dim cCust
    Set cCust = New clsCustomer    &lt;font color=green&gt;&apos; 사용자 클래스 생성&lt;/font&gt;
    cCust.init &quot;AROUT&quot;     &lt;font color=green&gt;&apos; AROUT란 ID의 사용자 정보를 가져옴&lt;/font&gt;
    
    &lt;font color=green&gt;&apos; 사용자의 회사명, 전화번호를 가져온다.&lt;/font&gt;
    Response.Write &quot;CustomerID : &quot; &amp; cCust.CustomerID &amp; &quot;&amp;lt;br&amp;gt;&quot;
    Response.Write &quot;CompanyName : &quot; &amp; cCust.CompanyName &amp; &quot;&amp;lt;br&amp;gt;&quot;
    Response.Write &quot;Phone : &quot; &amp; cCust.Phone &amp; &quot;&amp;lt;br&amp;gt;&quot;
&lt;/pre&gt;

&lt;p&gt;사용자 정보를 가져오기 위한 코딩이 상당히 간결하다는것을 알 수 있다. 단지 클래스 생성한 후에
클래스의 init 함수에 사용자 아이디만 인자로 넘겨주면 사용자에 대한 여러 정보를 손쉽게 반환해준다.&lt;/p&gt;

&lt;p&gt;사용자 정보를 가져오는 페이지가 100페이지라면 개발자들은 위의 사용자 정보오는 클래스만 100 페이지에서 이용하면 된다.
이런 클래스를 이용하게 되면 개발자가 100명이라해도 개발 코딩 스타일은 거의 일률적이기 때문에 나중에 한명이 개선한다고 해도
손쉽게 수정사항을 수정 할 수 있다. &lt;/p&gt;



&lt;p&gt;&lt;a name=&quot;c&quot; class=&quot;name&quot;&gt;3. 클래스 이용 확장&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;위에서 만든 클래스 이용시 한가지 단점이 있다. 위의 클래스는 고객의 ID 값만 넘겨주면 고객 정보를 반환해주는 역할을 했는데
고객 리스트를 보여주는 화면을 구성한다면?  아래 코드처럼 기존 asp 방식대로 고객 리스트 보여주는 화면을 만들것인가?
이 코딩방식의 문제점은 위에서도 언급했지만 고객 리스트를 보여주는 페이지가 100곳이라면 100 곳 모두 아래와 같은
코딩을 해야한다.&lt;/p&gt;

&lt;pre class=code&gt;
    ... 생략
    
    strSql = &quot;select CustomerID,CompanyName,Phone from Customers&quot;
    Set rs = DBCon.Execute(strSql)
    do until rs.eof
        db_CustomerID  = rs(0)
        db_CompanyName = rs(1)
        db_Phone       = rs(2)
        rs.movenext
    loop
    
    ... 생략
&lt;/pre&gt;

&lt;p&gt;위 코딩방식의 문제점을 해결하고자 아래와 같이 조금 편리하다 생각해서 코딩을 했다. 기존 asp 방식에 클래스를 함께 이용했다.&lt;/p&gt;


&lt;pre class=code&gt;
    ... 생략
    
    Dim cCust
    Set cCust = New clsCustomer
    strSql = &quot;select CustomerID from Customers&quot;
    Set rs = DBCon.Execute(strSql)
    do until rs.eof
        db_CustomerID  = rs(0)
        
        &lt;font color=green&gt;&apos; init 함수를 사용함으로써 쿼리문을 한번 더 날림&lt;/font&gt;
        cCust.Init db_CustomerID
        
        rs.movenext
    loop
    
    ... 생략
&lt;/pre&gt;

&lt;p&gt;조금은 머리를 굴린 방식의 처리지만..아주 안좋은 단점이 있다. 위에서 만든 clsCustomer 클래스를 보면 init 함수 이용시에
DB를 한번 갔다와서 사용자 정보를 가져온다. 즉 init 함수를 한번 이용할때마다 db 접속량이 그만큼 늘어난다. 
사용자가 만명이라면 단지 사용자 리스트를 뿌리기 위해서 만번 이상의의 쿼리문이 실행되는 것이다. 해서 위의 코딩방식은 오히려 기존 asp 코딩방식보다 못한 코딩이 되어버렸다. 
&lt;/p&gt;

&lt;p&gt;사용자 정보의 리스트를 클래스 형식으로 받기 위해선 아래와 같은 방법을 이용하면 된다.
클래스를 2개로 나누었다. 첫번째 clsCustomer 클래스는 단지 사용자의 속성만 정의된 클래스로써 다른 기타 메서드는 하나도 없다.
두번째 클래스는 clsCustomerDAO 이다. 이 클래스는 DB 접속을 통해서 사용자의 정보를 반환해주는 여러 함수를 담고있다.
DAO는 Data Access Object의 약자로서 MVC(Model View Controller)패턴에서 이용되는 용어인데...이 부분은 패턴 책이나. 자바/ C#관련
공부를 하면 좀 더 자세한 정보를 얻을수있다. 일단 넘어간다 -_-..
(참고로 여기선 clsCustomer/ clsCustomerDAO 이렇게 2 부분으로 클래스를 나눴는데 합쳐도 상관없다. 단지 클래스의 개념상의 분리를 위해서 나눈것이다.)
&lt;/p&gt;

&lt;pre class=code&gt;
    &lt;font color=green&gt;&apos;// Get/Let 속성만 정의된 클래스&lt;/font&gt;
    Class clsCustomer
        private m_CustomerID
        private m_CompanyName
        private m_Phone
        
        public property let CustomerID(p_CustomerID)
            m_CustomerID = p_CustomerID
        end property
        
        public property get CustomerID()
            CustomerID = m_CustomerID
        end property

        public property let CompanyName(p_CompanyName)
            m_CompanyName = p_CompanyName
        end property
        
        public property get CompanyName()
            CompanyName = m_CompanyName
        end property  
        
        public property let Phone(p_Phone)
            m_Phone = p_Phone
        end property
        
        public property get Phone()
            Phone = m_Phone
        end property
    End Class

    &lt;font color=green&gt;&apos;// Customer 관련 여러 Method가 있는 클래스&lt;/font&gt;
    Class clsCustomerDAO
        private DBCon
        
        &lt;font color=green&gt;&apos; 클래스 초기화&lt;/font&gt;
        Private Sub Class_Initialize 
            Dim strConn
            strConn = strConn&amp;&quot;Provider=SQLOLEDB.1;Persist Security Info=True;&quot;
            strConn = strConn&amp;&quot;Data Source=;&quot;   &lt;font color=green&gt;&apos; Server Name&lt;/font&gt;
            strConn = strConn&amp;&quot;User ID=sa;&quot;     &lt;font color=green&gt;&apos; User ID&lt;/font&gt;
            strConn = strConn&amp;&quot;Password=;&quot;      &lt;font color=green&gt;&apos; User Password&lt;/font&gt;
            strConn = strConn&amp;&quot;Initial Catalog=NorthWind;&quot; &lt;font color=green&gt;&apos; DataBase&lt;/font&gt;
            
            Set DBCon = Server.CreateObject(&quot;ADODB.Connection&quot;)
            DBCon.Open strConn    
        End Sub
        &lt;font color=green&gt;&apos; 클래스 종료&lt;/font&gt;
        Private Sub Class_Terminate   &apos; Setup Terminate event.
            if DBCon.State = 2 then DBCon.Close
            Set DBCon = Nothing
        End Sub
        
        &lt;font color=green&gt;&apos; CustomerID를 인자로 주면 Customer의 정보를 반환함&lt;/font&gt;
        Public Sub init(p_cls, id)
            Dim rs : Set rs = Server.CreateObject(&quot;ADODB.RecordSet&quot;)
            Dim strSql
            
            strSql = &quot;select CustomerID,CompanyName,Phone from Customers Where CustomerID=&apos;&quot; &amp; id &amp; &quot;&apos;&quot;
            Set rs = DBCon.Execute(strSql)
            if not rs.eof then
                p_cls.CustomerID  = rs(0)
                p_cls.CompanyName = rs(1)
                p_cls.Phone       = rs(2)
            end if
            rs.Close
            Set rs = nothing
        End Sub
        
        &lt;font color=green&gt;&apos; Customer 정보를 모두 가져옴&lt;/font&gt;
        Public Function getList()
            Dim rs : Set rs = Server.CreateObject(&quot;ADODB.RecordSet&quot;)
            Dim i : i = 1
            Dim cCust
            Dim m_arrList()     &lt;font color=green&gt;&apos; 사용자 정보를 반환하기 위한 배열&lt;/font&gt;
            
            Set rs = DBCon.Execute(&quot;select CustomerID,CompanyName,Phone from Customers&quot;)
            do until rs.eof
                ReDim Preserve m_arrList(i)
                Set cCust = New clsCustomer
                
                cCust.CustomerID  = rs(0)
                cCust.CompanyName = rs(1)
                cCust.Phone       = rs(2)
                Set m_arrList(i-1) = cCust
                
                i = i + 1
                rs.movenext
            loop
            rs.Close
            Set rs = nothing
            getList = m_arrList
        End Function        
    End Class
&lt;/pre&gt;    


&lt;p&gt;위의 코드를 이용해서 사용자 ID만 넘겨주면 사용자 정보를 반환해주는 코드를 보자&lt;/p&gt;

&lt;pre class=code&gt;
    Dim cCustDAO : Set cCustDAO = New clsCustomerDAO
    Dim cCust : Set cCust = New clsCustomer
        
    cCustDAO.init cCust, &quot;AROUT&quot;
    Response.Write &quot;CustomerID : &quot; &amp; cCust.CustomerID &amp; &quot;&amp;lt;br&amp;gt;&quot;
    Response.Write &quot;CompanyName : &quot; &amp; cCust.CompanyName &amp; &quot;&amp;lt;br&amp;gt;&quot;
    Response.Write &quot;Phone : &quot; &amp; cCust.Phone &amp; &quot;&amp;lt;br&amp;gt;&quot;
&lt;/pre&gt;

&lt;p&gt;cCustDAO.init cCust, &quot;AROUT&quot; 이 부분을 보면 제일 만든 클래스의 init 함수와는 다르게 인자를 하나 더 넘겨준다.
이 인자는 clsCustomer 클래스의 인스턴스인데 이렇게 하는 이유는 asp에서 상속이 안되기 때문이다. -_-;;
상속만 된다면 clsCustomer 클래스를 clsCustomerDAO에서 상속해서 이용하면 되는데 그게 안되서 인자로 넘겨줘버리는 것이다.
머리아픈 얘긴 넘어가고...단지 init 함수의 인자가 하나 더 늘어난것만 확인하자.&lt;/p&gt;

&lt;p&gt;자! 이제 사용자 정보를 리스트로 얻어보자 이 사용자 리스트 얻는 함수는 clsCustomerDAO 클래스 내에 getList 함수를 이용하면 된다.
사용법은 아래처럼!&lt;/p&gt;

&lt;pre class=code&gt;
    Dim datas
    datas = cCustDAO.getList()
    for i = 0 to ubound(datas) - 1
        Response.Write &quot;CustomerID : &quot; &amp; datas(i).CustomerID &amp; &quot;&amp;lt;br&amp;gt;&quot;
        Response.Write &quot;CompanyName : &quot; &amp; datas(i).CompanyName &amp; &quot;&amp;lt;br&amp;gt;&quot;
        Response.Write &quot;Phone : &quot; &amp; datas(i).Phone &amp; &quot;&amp;lt;hr&amp;gt;&quot;
    next
&lt;/pre&gt;    

&lt;p&gt;getList 함수에서 사용자 정보의 클래스를 배열로 반환 해주기 때문에 간단히 위의 코드처럼 루프 돌면서 사용자 리스트를 이용하면 된다.
이런 식으로 자주 이용하는 사용자에 관한 모든 정보를 클래스로 만들어 둔다면 개발초기 당시엔 클래스 만드느라 이리저리 고생하지만
한번 제대로 만들어 두면 나중에 개발할때나 개선할때 상당히 편리하다. 단지 인자만 &apos;틱&apos;하고 넘겨주면 &apos;틱&apos;하고 데이타가 나오니깐 말이다.&lt;/p&gt;

&lt;p&gt;그렇다고 별로 사용되지도 않는 정보들..예를 들자면 탈퇴한 회원 목록 같은것.. 이런 거의 쓰이지도 않는 정보 때문에 &apos;탈퇴한 회원 클래스&apos;를 
만드는 것은 정말 쓸데없는 짓이다. 그러니 이런 자주 사용되지 않는 정보들은 클래스로 만들 필요가 없다.&lt;/p&gt;

&lt;p&gt;원래는 Class 가장 기초부터 적어볼까 했는데...기초 적는게 더 힘들다. 기초는 그냥 존내 야리면 어느순간 퍼뜩 깨달음(?)이 생긴다.
일단 사용해 보는거다 -_-... 일단 사용해보고 어느정도 개념이 생겼다면 그 때 책봐도 된다. &lt;/p&gt;
&lt;p&gt;(근데 폰트가 꾸리꾸리한가.. 왜 소스의 들여쓰기가 까칠하게 잘 안맞냐 -_-;;)&lt;/p&gt;

&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Hotmail의 DHTML EDITOR 편집기를 이용해보자.</title>
      <id>http://www.mungchung.com/xe/4144</id>
      <published>2006-02-04T10:15:52+09:00</published>
      <updated>2010-12-30T14:51:41+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.mungchung.com/xe/4144"/>
      <link rel="replies" type="text/html" href="http://www.mungchung.com/xe/4144#comment"/>
      <author>
         <name>뭉충닷컴</name>
                  <uri>http://www.mungchung.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;DHTML EDITOR하나 훔쳐왔다. 대개 웹상에서 편집을 하려면 나모, 넝쿨, 태그프리 Active X 편집기등등을 이용한다.
이런 편집기들이야 전문 HTML 편집기라서 여러가지 다양한 기능을 제공하지만 대개 사용자는 단순한 기능만
이용한다.(내가 그러니 다른 사람들도 그럴것이라 생각됨 -_-;;)
비싸게 돈 주고 산것을 단순히 글자에 색 입히기로만 사용된다 -_-
이 편집기가 비싸기도 하거니와 개발할때도 이리저리 괴롭다. 설치할때, 개발할때 이리저리 괴롭고
힘들게 달아두었다고 해도 사용하다보면 이런 저런 편집기의 오류가 간간히 나타난다.&lt;/p&gt;

&lt;p&gt;해서 DHTML EDITOR 뭔가 좋은것 없나..예전에 몇번씩 살펴보다가 썩 맘에 드는것이 없어서
그냥 넘어가곤 했는데 이번에 필요할 일이 생겨서 제대로 한번 구해봤다. 물론 구해본건 아니고
몇백만?몇천만 유저들이 이용하는 HOTMAIL에서 편지쓸때 이용되는 DHTML EDITOR 부분만 쏙~ 훔쳐왔다.&lt;/p&gt;

&lt;p&gt;어차피 DHTML EDITOR이 client단 script이기 때문에 누구나 좀만 알면 훔쳐올수 있는데..요것 걸릴려나 -_-;;
아무튼 소스가져와서 사용하기 편리하게 이것 저것 고쳐놓아서 올린다.
소스는 다른것 볼필요 없고 write_form.html, write_proc.asp 이 2개만 보면 된다.
다른 파일들은 좀 더 미세한 수정을 하고자할때 각자 수정하면 된다.&lt;/p&gt;

&lt;p&gt;사용법은 간단하다. write_form.html파일을 보자

&lt;pre class=&quot;code&quot;&gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;DHTML Editor&amp;lt;/title&amp;gt;
    &lt;font color=red&gt;&amp;lt;script language=javascript src=hotmail_dhtmleditor.js&amp;gt;&amp;lt;/script&amp;gt;&lt;/font&gt;
    &amp;lt;style&amp;gt;
        td{font-size:9pt}
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;script language=javascript&amp;gt;
    function goSubmit(f) {
        // 편집기의 데이타를 form의 content 값에 넣는다.
        &lt;font color=red&gt;f.content.value = getDhtmlData();&lt;/font&gt;
        return true;   
    }
&amp;lt;/script&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;form name=&lt;font color=red&gt;frm&lt;/font&gt; method=post action=write_proc.asp onSubmit=&quot;return goSubmit(this)&quot;&amp;gt;
&amp;lt;table width=650 border=1&amp;gt;
    &amp;lt;tr&amp;gt;
        &amp;lt;td width=100 align=center&amp;gt;제목&amp;lt;/td&amp;gt;
        &amp;lt;td width=550&amp;gt;&amp;lt;input type=text name=subject size=50&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;tr&amp;gt;
        &amp;lt;td align=center&amp;gt;내용&amp;lt;/td&amp;gt;
        &amp;lt;td&amp;gt;
            &lt;font color=red&gt;&amp;lt;textarea style=display:none name=content&amp;gt;&amp;lt;/textarea&amp;gt;
            &amp;lt;script language=javascript&amp;gt;initDhtmlEditor(&apos;frm&apos;,&apos;content&apos;);&amp;lt;/script&amp;gt;&lt;/font&gt;
        &amp;lt;/td&amp;gt;
    &amp;lt;/tr&amp;gt;
    &amp;lt;tr&amp;gt;
        &amp;lt;td colspan=2&amp;gt;&amp;lt;input type=submit&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;/tr&amp;gt;
&amp;lt;/table&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;

&lt;p&gt;실질적으로 필요한 부분만 빨간색으로 강조해두었다.
기존 게시판에 혹 편집기 달아둘일 생기면 빨간색 부분만 수정하거나 주의해서 보면 쉽게 달 수 있을것이다.&lt;/p&gt;

&lt;p&gt;일단 DHTML EDITOR을 이용하기 위해서 스크립트를 인클루드 한다.&lt;/p&gt;
&lt;pre class=code&gt;&amp;lt;script language=javascript src=hotmail_dhtmleditor.js&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;

&lt;p&gt;그런후 기존 사용하던 글 입력창..아마 99%는 textarea 태그일것이다. 요것 style태그를 이용해서 숨김으로 해둔다. (style=display:none 요렇게)
그런후 아랫부분에 DHTML EDITOR을 초기화시키는 initDhtmlEditor 함수를 실행시키는데 2개의 인자를 던져준다.
하나는 form의 이름이고 다른 하나는 textarea 의 이름이다. 여기 예제소스는 폼이름이 frm , textarea이름이 content라 정의했다.&lt;/p&gt;

&lt;pre class=code&gt;&amp;lt;textarea style=display:none name=content&amp;gt;&amp;lt;/textarea&amp;gt;
&amp;lt;script language=javascript&amp;gt;initDhtmlEditor(&apos;frm&apos;,&apos;content&apos;);&amp;lt;/script&amp;gt;&lt;/pre&gt;

&lt;p&gt;이정도 작업만 해주고 실행시키면 편집기가 웹상에서 떡하니 떠있는 모습을 볼 수 있을것이다.
안뜬다면 아마..경로상의 문제가 있을테니 이것저것 잘 살펴봐라 -_-..
편집기 달아두었으면 이 편집기의 데이타를 다시 textarea에 넣는 일을 해야한다.
아래처럼 getDhtmlData() 함수를 이용하면 편집기의 데이타를 얻어올수 있는데 이 값을 content값에 넣었다.&lt;/p&gt;

&lt;pre class=code&gt;f.content.value = getDhtmlData();&lt;/pre&gt;

&lt;p&gt;이렇게만 해주고 submit 하면 끝이다. 이제 이 값을 DB에 넣어보자. 편집기를 이용하느라 이리저리 태그가 많이 사용되서
DB에 그냥 입력하면 오류가날수 있으므로 조금 데이터를 가공해서 넣어야 한다. 이 데이터 가공함수는
write_proc.asp 페이지 열어보면 2개의 함수가있다. 하나는 DB에 입력할때 쓰이는 함수 다른 하나는 DB에서 불러올때 쓰이는 함수이다.&lt;/p&gt;

&lt;pre class=code&gt;
&apos; DB에 입력시
Function inputDHTML(CheckValue)
    if CheckValue &lt;&gt; &quot;&quot; then
        CheckValue = replace(CheckValue, &quot;&quot;&quot;&quot;, &quot;chr(34)&quot;)
        CheckValue = replace(CheckValue, &quot;&apos;&quot;, &quot;chr(39)&quot;)
        CheckValue = replace(CheckValue, &quot;,&quot;, &quot;chr(44)&quot;)
        CheckValue = replace(CheckValue, &quot;&amp;nbsp;&quot;, &quot;&lt;space&gt;&quot;)
        inputDHTML = CheckValue
    end if
End Function
&apos; DB에서 가져올때
Function outputDHTML(CheckValue)
    if CheckValue &lt;&gt; &quot;&quot; then
        CheckValue = replace(CheckValue, &quot;chr(34)&quot;, &quot;&quot;&quot;&quot;)
        CheckValue = replace(CheckValue, &quot;chr(39)&quot;, &quot;&apos;&quot;)
        CheckValue = replace(CheckValue, &quot;chr(44)&quot;, &quot;,&quot;)
        CheckValue = replace(CheckValue, &quot;&lt;space&gt;&quot;, &quot;&amp;nbsp;&quot;)
        outputDHTML = CheckValue
    end if
End Function
&lt;/pre&gt;

&lt;p&gt;submit된 페이지에서 content 값을 inputDHTML함수 이용해서 DB에 넣고 글 보기 화면에선 outputDHTML 함수로 뿌려주면 된다.&lt;/p&gt;

&lt;p&gt;마지막으로 글 수정화면에서 편집기에 글 작성시 적었던 내용이 미리 들어가있어야 하는데 요건 아주 간단하다. 아래 소스보면 이해될꺼다 -_-&lt;/p&gt;
&lt;pre class=code&gt;&amp;lt;textarea style=display:none name=content&amp;gt;
&lt;font color=red&gt;요기에 내용이 들어가면 자동으로 편집기에 요 내용이 들어가지롱~&lt;/font&gt;
&amp;lt;/textarea&amp;gt;
&amp;lt;script language=javascript&amp;gt;initDhtmlEditor(&apos;frm&apos;,&apos;content&apos;);&amp;lt;/script&amp;gt;&lt;/pre&gt;


&lt;p&gt;편집기 사용법 끝났다. 힘들다 -_-;; 역시나 귀찮아서 날림 작성이니 모르는것은 질문으로!&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>Tabular Data Control 응용 - 제목 Sort (정렬) 쉽게 하기</title>
      <id>http://www.mungchung.com/xe/4140</id>
      <published>2006-01-27T09:41:14+09:00</published>
      <updated>2011-03-19T09:50:27+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.mungchung.com/xe/4140"/>
      <link rel="replies" type="text/html" href="http://www.mungchung.com/xe/4140#comment"/>
      <author>
         <name>뭉충닷컴</name>
                  <uri>http://www.mungchung.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;
&lt;p&gt;게시판의 타이틀..그러니깐 글번호, 제목, 작성자..등등을 클릭하면 해당 항목에 맞게 정렬이 되는 기능이 있는데
이게 사실 구현하기 어려운것보단 은근히 개노가다이다.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;이런 개노가다를 TDC를 이용하면 손쉽게 해결할수 있다. MSDN에서 TDC관련 문서를 보면 잘 나와있긴하지만..간단한 함수로
만들어서 개발자가 몇가지 작업만 있으면 바로 적용 할 수 있도록 만들었다. 
&lt;/p&gt;
&lt;p&gt;헌데 한가지 문제가 있다. 이 정렬기능을 이용하려면 TDC데이타를 한번에 모두 뿌려줘야한다.
예를 들어서 페이징 할때 10개의 페이지가 있다고 하면 10개 페이지 해당분량의 데이타를 클라이언트가 모두
받아야..정렬이 제대로 이루어진다는거다.&lt;/p&gt;

&lt;p&gt;어찌보면 아주 당연한건데 말로풀어 설명하니 존내 힘들다. 그래서 그냥 넘어간다. -_-&lt;/p&gt;


&lt;pre class=&quot;code&quot;&gt;
&amp;lt;script language=javascript&amp;gt;
function TdcSort(tdc_id) {
    var srcEl = event.srcElement;
    srcNm = srcEl.innerHTML
    
    if (srcNm.search(&quot;▲&quot;) == -1 &amp;&amp; srcNm.search(&quot;▼&quot;) == -1) {
        srcEl.innerHTML = srcNm + &quot;▲&quot;;
        oList.Sort = tdc_id;
    } else if (srcNm.search(&quot;▼&quot;) &amp;gt; -1) {
        srcNm = srcNm.replace(&quot;▼&quot;,&quot;&quot;);
        srcEl.innerHTML = srcNm + &quot;▲&quot;;
        oList.Sort = tdc_id;
    } else if (srcNm.search(&quot;▲&quot;) &amp;gt; -1) {
        srcNm = srcNm.replace(&quot;▲&quot;,&quot;&quot;);
        srcEl.innerHTML = srcNm + &quot;▼&quot;;
        oList.Sort = &quot;-&quot;+tdc_id;
    }
    oList.reset();
}
&amp;lt;/script&amp;gt;

&amp;lt;table width=&quot;680&quot; cellpadding=&quot;1&quot; cellspacing=&quot;1&quot; border=&quot;0&quot; DataSrc=&quot;#oList&quot; &amp;gt;
    &amp;lt;thead&amp;gt;
    &amp;lt;tr class=&quot;TD_SBJ&quot;&amp;gt;
        &amp;lt;td width=&quot;40&quot;&amp;gt;No&amp;lt;/td&amp;gt;
        &amp;lt;td width=&quot;90&quot;&amp;gt;&lt;font color=blue&gt;&amp;lt;a href=&quot;#&quot; onclick=&quot;TdcSort(&apos;keyword&apos;)&quot;&amp;gt;약자&amp;lt;/a&amp;gt;&lt;/font&gt;&amp;lt;/td&amp;gt;
        &amp;lt;td width=&quot;150&quot;&amp;gt;&lt;font color=blue&gt;&amp;lt;a href=&quot;#&quot; onclick=&quot;TdcSort(&apos;korean&apos;)&quot;&amp;gt;한글&amp;lt;/a&amp;gt;&lt;/font&gt;&amp;lt;/td&amp;gt;
        &amp;lt;td width=&quot;200&quot;&amp;gt;영어&amp;lt;/td&amp;gt;
        &amp;lt;td width=&quot;120&quot;&amp;gt;유의어&amp;lt;/td&amp;gt;
        &amp;lt;td width=&quot;80&quot;&amp;gt;액숑&amp;lt;/td&amp;gt;
    &amp;lt;/tr&amp;gt;
    &amp;lt;/thead&amp;gt;
    &amp;lt;tbody&amp;gt;
    &amp;lt;tr&amp;gt;
        &amp;lt;td class=&quot;TD_COT&quot; align=&quot;center&quot;&amp;gt;&amp;lt;span DATAFLD=&quot;num&quot; DATAFORMATAS=&quot;HTML&quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;td class=&quot;TD_COT&quot; align=&quot;center&quot; style=background-color:cccccc&amp;gt;&amp;lt;span DATAFLD=&quot;keyword&quot; DATAFORMATAS=&quot;HTML&quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;td class=&quot;TD_COT&quot;&amp;gt;&amp;lt;span DATAFLD=&quot;korean&quot; DATAFORMATAS=&quot;HTML&quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;td class=&quot;TD_COT&quot;&amp;gt;&amp;lt;span DATAFLD=&quot;english&quot; DATAFORMATAS=&quot;HTML&quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;td class=&quot;TD_COT&quot;&amp;gt;&amp;lt;span DATAFLD=&quot;similar&quot; DATAFORMATAS=&quot;HTML&quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;
        &amp;lt;td class=&quot;TD_COT&quot; align=&quot;center&quot;&amp;gt;&amp;lt;span DATAFLD=&quot;auction&quot; DATAFORMATAS=&quot;HTML&quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt;
    &amp;lt;/tr&amp;gt;
    &amp;lt;tbody&amp;gt;
    &amp;lt;tfoot&amp;gt;
    &amp;lt;tr id=&quot;nodata&quot; style=&quot;display:none&quot;&amp;gt;
        &amp;lt;td colspan=&quot;10&quot; align=&quot;center&quot; height=&quot;30&quot;&amp;gt;데이타가 없습니다.&amp;lt;/td&amp;gt;
    &amp;lt;/tr&amp;gt;
    &amp;lt;/tfoot&amp;gt;
&amp;lt;/table&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
잘 보면 HTML 소스코드 부분에 &amp;lt;a href=&quot;#&quot; onclick=&quot;TdcSort(&apos;keyword&apos;)&quot;&gt;약자&amp;lt;/a&gt; 이 부분이 보인다. 이건 keyword로 정렬을 하겠다는 거다.
에잇! 귀찮아서 그만 적는다.
나중에 콘디숑 좋으면 추가해서 적던가 정리하던가 하겠다.&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>스크립트(Script) 코드를 암호화 시켜보자(Encode/Decode)</title>
      <id>http://www.mungchung.com/xe/4137</id>
      <published>2005-06-10T15:33:01+09:00</published>
      <updated>2010-08-05T21:55:02+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.mungchung.com/xe/4137"/>
      <link rel="replies" type="text/html" href="http://www.mungchung.com/xe/4137#comment"/>
      <author>
         <name>뭉충닷컴</name>
                  <uri>http://www.mungchung.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;스크립트 코드를 보안상 이유로 인코드를 하는 경우 있는데 아시는 분들은 다 아시겠지요 -_-
도움말 보면 왜 사용해야하는지 사용상 주의 사항들 그런것 잘 나와 있습니다. 그러니 자세한 내용은 도움말 참조하세요.
&lt;p&gt;
&lt;br&gt;&lt;br&gt;

&lt;b&gt;*) 스크립트 Encode&lt;/b&gt;

&lt;p&gt;일단 encode 하는 프로그램 다운 받아야 합니다. 
&lt;a href=http://www.microsoft.com/downloads/details.aspx?displaylang=ko&amp;FamilyID=e7877f67-c447-4873-b1b0-21f0626a6329 target=_blank&gt;http://www.microsoft.com/downloads/details.aspx?displaylang=ko&amp;FamilyID=e7877f67-c447-4873-b1b0-21f0626a6329&lt;/a&gt;
 여기 가서 받으면 됩니다. 다운 받아서 설치합니다. 그런후 아래 코드를 복사해서 test.html 파일로 만듭니다.
&lt;/p&gt;

&lt;xmp style=&quot;background:f4f4f4;padding:5 5 5 5&quot;&gt;
&lt;script language=&quot;vbscript&quot;&gt;
&apos; 스크립트 Encoder 예제
sub test()
    msgbox (&quot;클릭했어요&quot;)
end sub
&lt;/script&gt;
&lt;input type=&quot;button&quot; value=&quot;버튼입니다&quot; onclick=&quot;test()&quot;&gt;
&lt;/xmp&gt;

&lt;p&gt;
이 test.html 파일의 스크립트 부분을 encode 하면 도스창에서 아래와 같은 명령을 내리면 됩니다.
(혹 SRCENC.exe를 못찾는 경우 Script Encoder가 설치된 디렉토리로 가서 실행시키면 됩니다.)
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;font color=blue&gt;SRCENC &quot;원본파일&quot; &quot;내보낼파일&quot;&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;


&lt;p&gt;이렇게 해서 내보낸 파일의 소스를 보면 아래와 같습니다.&lt;/p&gt;

&lt;xmp style=&quot;background:f4f4f4;padding:5 5 5 5&quot;&gt;
&lt;script language=&quot;VBScript.Encode&quot;&gt;
&apos; 스크립트 Encoder 예제
&apos;**Start Encode**#@~^NQAAAA==@#@&amp;/;(PD+/D`*@#@&amp;,P~Ps/L8K6PvE클릭했어요J*@#@&amp;U[PkE(@#@&amp;PQoAAA==^#~@&lt;/script&gt;
&lt;input type=&quot;button&quot; value=&quot;버튼입니다&quot; onclick=&quot;test()&quot;&gt;
&lt;/xmp&gt;
&lt;br&gt;&lt;br&gt;

&lt;b&gt;*) 스크립트 Decode&lt;/b&gt;
&lt;p&gt;인코딩한 파일을 test1.html 이라했을때 이 파일을 다시 decode 하는 방법은 아래 유틸을 다운받아야 합니다.
&lt;a href=http://www.virtualconspiracy.com/index.php?page=scrdec/download  target=_blank&gt;http://www.virtualconspiracy.com/index.php?page=scrdec/download&lt;/a&gt;
이 프로그램 다운 받은 후에 도스창에서 다음과같은 명령 실행하면 인코딩된 스크립트를 디코딩 해줍니다.&lt;/p&gt;

&lt;p&gt;&lt;font color=blue&gt;&lt;b&gt;scrdec18.exe &quot;인코딩된파일&quot; &quot;내보낼파일&quot;&lt;/b&gt;&lt;/font&gt;&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
   <entry>
      <title>dll을 이용한 로그인</title>
      <id>http://www.mungchung.com/xe/4135</id>
      <published>2005-11-25T23:44:16+09:00</published>
      <updated>2011-01-25T11:55:33+09:00</updated>
      <link rel="alternate" type="text/html" href="http://www.mungchung.com/xe/4135"/>
      <link rel="replies" type="text/html" href="http://www.mungchung.com/xe/4135#comment"/>
      <author>
         <name>뭉충닷컴</name>
                  <uri>http://www.mungchung.com</uri>
               </author>
            <content type="html">&lt;div class=&quot;xe_content&quot;&gt;&lt;p&gt;좀 여유가 생겨서 뭔가 적을것 없을까 하다가 dll을 이용한 로그인 방법에 대해서 적는다.
아주 간단한 구조의 dll을 이용한 로그인이지만 실제로 VB와 asp와의 연동을 많이 해보지 않은 분들은
이것 저것 꽤나 괴로운 작업이 될수 있다. &lt;/p&gt;

&lt;p&gt;코드야 어렵지 않다. asp 몇개월만해도 이해할수 있을 정도의 코드다 하지만 실제로 적용하면
코드에서 태클걸리는 것이 아니라 VB의 특성과 시스템적인 특성들때문에 이것 저것 괴로워지고 몰라서 
밤새고 그런다. (나도 마찬가지로 꽤나 괴로운적 많았다 -_-)&lt;/p&gt;

&lt;p&gt;그래서 순전히 내 주관적인 방법으로 디버깅 하고 에러 찾아내는 방법까지 적어본다. 어떻게 보면 나도 잘 몰라서 무식하게 해결하는 방법일수도 있다. 
그럴때는 좀더 좋은 방법 있으면 답글 남겨주면 고맙게 받아들이겠다.&lt;/p&gt;

&lt;p&gt;참고로 소스코드를 만들고 보니 데브피아에서 출간한 &quot;실전을 위한 ASP&quot;에 나와 있는 dll을 이용한 로그인 방법과 거의 유사한
예제가 되버렸다. -_- 오죽했음 반환된 값을 에러 번호의 내용까지도 똑같다. -_- (절대 보고 베낀것이 아니다 -_-;;; )&lt;/p&gt;


&lt;p&gt;일단 MS-SQL 2000기준으로 작성된 예제이다. 일단 테스트용 회원DB가 필요한데 첨부파일 다운받으면
example_query.sql 파일이 있는데 이 파일을 쿼리분석기에서 실행한다.&lt;/p&gt;

&lt;p&gt;테스트 DB를 만들었다면 이제 본격적으로 시작해보자. 글 구성은 다음과 같다.&lt;/p&gt;


&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;#a&quot;&gt;1. dll 만들기&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;#b&quot;&gt;2. dll을 asp 에서 이용&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;#c&quot;&gt;3. 효과적인 dll 디버깅 방법&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;#d&quot;&gt;4. Visual Studio에서 dll 디버깅하기&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;#e&quot;&gt;5. dll 배포&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;a name=&quot;a&quot; class=&quot;name&quot;&gt;1. dll 만들기&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;일단 VB로 dll을 작성해보자.&lt;/p&gt;

&lt;p&gt;1. VB 실행 시킨후에 [새 프로젝트]에서 ActiveX DLL 을 선택한다.&lt;br&gt;
2. [프로젝트]-[참조] 에서 &quot;Microsoft ActiveX Data Objects 2.x Library&quot;을 참조시킨다.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;여기서 버젼은 2.6, 2.7, 2.8..등등 있을텐데 아무거나 해도 예제 실행시키는 데도 별 상관없겠으나&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;그래도 버젼 높은것이 좋으니 높은 버젼 있음 그걸로 선택하자&lt;br&gt;
3. 프로젝트를 선택한후 마우스 오른쪽 버튼을 눌러서 &quot;프로젝트 속성&quot;을 클릭하자&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img src=/mianamssi/articles/img/dlllogin/1.gif&gt;&lt;br&gt;
4. 프로젝트 속성에서 프로젝트 이름을 Mungchung로 바꾼다.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img src=/mianamssi/articles/img/dlllogin/2.gif&gt;&lt;br&gt;
5. 클래스를 선택한후에 클래스 이름을 clsLogin으로 바꾼다.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img src=/mianamssi/articles/img/dlllogin/3.gif&gt;&lt;br&gt;
6. 아래 소스코드를 적는다. (귀찮으면 첨부파일 다운받으면됨)&lt;/p&gt;

&lt;xmp class=code&gt;
Private m_Conn As ADODB.Connection
Private m_User_Idx As Integer
Private m_User_Name As String

&apos;// 클래스 초기화
Private Sub Class_Initialize()
    Dim connectStr As String

    connectStr = &quot;&quot;
    connectStr = connectStr &amp; &quot;Provider=SQLOLEDB.1;&quot;
    connectStr = connectStr &amp; &quot;Data Source=localhost;&quot;
    connectStr = connectStr &amp; &quot;Initial Catalog=TEST_DB;&quot;
    connectStr = connectStr &amp; &quot;User ID=sa;&quot;
    connectStr = connectStr &amp; &quot;Password=;&quot;
    
    Set m_Conn = New ADODB.Connection
    m_Conn.ConnectionString = connectStr
    m_Conn.Open
End Sub

&apos;// 사용자 고유키값
Public Function getUserIdx() As Integer
    getUserIdx = m_User_Idx
End Function
&apos;// 사용자 이름

Public Function getUserName() As String
    getUserName = m_User_Name
End Function

&apos;// 로그인 메서드
Public Function doLogin(ByVal id As String, ByVal pw As String) As Integer
    Dim retVal As Integer
    Dim db_User_Pw As String
    Dim db_User_Name As String
    Dim db_User_Idx As String
    Dim strSql As String
    Dim rs As ADODB.Recordset
    Set rs = New ADODB.Recordset
    
    strSql = &quot;Select User_Idx, User_Name, User_Pw From UserBasic Where User_Id=&apos;&quot; &amp; id &amp; &quot;&apos;&quot;
    Set rs = m_Conn.Execute(strSql)
    
    If rs.EOF Then
        retVal = 1  &apos; 존재하지 않는 아이디
    Else
        db_User_Idx = rs(0)
        db_User_Name = rs(1)
        db_User_Pw = rs(2)
        
        If CStr(db_User_Pw) &lt;&gt; CStr(pw) Then
            retVal = 2  &apos; 비밀번호가 일치하지 않음
        Else
            m_User_Idx = db_User_Idx
            m_User_Name = db_User_Name
            retVal = 3  &apos; 로그인 성공!
        End If
    End If
    
    rs.Close
    Set rs = Nothing

    doLogin = retVal
End Function

&apos;// 클래스 종료
Private Sub Class_Terminate()
    m_Conn.Close
    Set m_Conn = Nothing
End Sub
&lt;/xmp&gt;

&lt;p&gt;
Class_Initialize함수와 Class_Terminate함수는 클래스가 로드/언로드 될때 자동으로 실행되는 함수이다.
여기선 Class_Initialize 함수에 DB 연결 구문을 넣어서 클래스가 로드되면 바로 DB에 연결하도록 했고
Class_Terminate함수에선 클래스 언로드 시키면 바로 DB연결 끊도록 했다. 요렇게 처리 함으로써 asp 상에선
굳이 DB연결 관련 변수를 전혀 사용할 필요가 없다.
&lt;/p&gt;

&lt;xmp class=code&gt;
Private Sub Class_Initialize()
    Dim connectStr As String

    connectStr = &quot;&quot;
    connectStr = connectStr &amp; &quot;Provider=SQLOLEDB.1;&quot;
    connectStr = connectStr &amp; &quot;Data Source=localhost;&quot;
    connectStr = connectStr &amp; &quot;Initial Catalog=TEST_DB;&quot;
    connectStr = connectStr &amp; &quot;User ID=sa;&quot;
    connectStr = connectStr &amp; &quot;Password=;&quot;
    
    Set m_Conn = New ADODB.Connection
    m_Conn.ConnectionString = connectStr
    m_Conn.Open
End Sub
...
Private Sub Class_Terminate()
    m_Conn.Close
    Set m_Conn = Nothing
End Sub
&lt;/xmp&gt;

&lt;p&gt;doLogin 메서드가 실질적으로 로그인을 처리하는 함수이다. 인자는 아이디와 비밀번호이고 반환값은 정수형으로 반환해준다.
로그인 성공 했을 경우엔 사용자 이름과 사용자 고유키값을 멤버변수(m_User_Name, m_User_Idx)에 저장한다.
코드가 그렇게 어렵지 않으므로 자세한 설명은 생략한다 -_-&lt;/p&gt;

&lt;xmp class=code&gt;
Public Function doLogin(ByVal id As String, ByVal pw As String) As Integer
    Dim retVal As Integer
    Dim db_User_Pw As String
    Dim db_User_Name As String
    Dim db_User_Idx As String
    Dim strSql As String
    Dim rs As ADODB.Recordset
    Set rs = New ADODB.Recordset
    
    strSql = &quot;Select User_Idx, User_Name, User_Pw From UserBasic Where User_Id=&apos;&quot; &amp; id &amp; &quot;&apos;&quot;
    Set rs = m_Conn.Execute(strSql)
    
    If rs.EOF Then
        retVal = 1  &apos; 존재하지 않는 아이디
    Else
        db_User_Idx = rs(0)
        db_User_Name = rs(1)
        db_User_Pw = rs(2)
        
        If CStr(db_User_Pw) &lt;&gt; CStr(pw) Then
            retVal = 2  &apos; 비밀번호가 일치하지 않음
        Else
            m_User_Idx = db_User_Idx
            m_User_Name = db_User_Name
            retVal = 3  &apos; 로그인 성공!
        End If
    End If
    
    rs.Close
    Set rs = Nothing

    doLogin = retVal
End Function
&lt;/xmp&gt;

&lt;p&gt;2개의 getter 속성을 추가했다. 보통 로그인 하면 그 사용자의 이름이나 고유키값들을 DB에서 읽어와서 
세션으로 준다. 그 사용자 이름/ 고유키값을 세션으로 주기 위해서 값을 얻어와야 하는데 그 값을 주는 함수가
getUserIdx, getUserName이다. &lt;/p&gt;

&lt;xmp class=code&gt;
Public Function getUserIdx() As Integer
    getUserIdx = m_User_Idx
End Function

Public Function getUserName() As String
    getUserName = m_User_Name
End Function
&lt;/xmp&gt;


&lt;p&gt;소스 설명은 간단하게 이정도로 마치고...생성한 프로젝트를 저장하고 dll로 만든다.
그리고는 [시작]-[실행]창에서 cmd를 치면 명령어 프롬프트가 나오는데 거기서 regsvr32 mungchung.dll로 이 dll을 등록한다.
(혹 regsvr32명령어가 안된다면 윈도우98/XP는 c:\windows\system32, 윈도우2000은 c:\winnt\system32 디렉토리로 이동한후에 다시 해보면된다)
&lt;/p&gt;


&lt;p&gt;&lt;a name=&quot;b&quot; class=&quot;name&quot;&gt;2. dll을 asp 에서 이용&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
이제 등록한 dll파일을 asp페이지에서 이용해보자 먼저 로그인 하는 페이지이다.
엄청 간단하다 -_-. 설명 필요 없다.
&lt;/p&gt;
&lt;b&gt;[login.asp]&lt;/b&gt;
&lt;xmp class=code&gt;
&lt;form name=frm method=post action=login_proc.asp&gt;
id : &lt;input type=text name=id&gt;&lt;br&gt;
pw : &lt;input type=text name=pw&gt;&lt;br&gt;
&lt;input type=submit&gt;
&lt;/form&gt;
&lt;/xmp&gt;

&lt;p&gt;다음은 로그인을 처리하는 페이지이다.&lt;/p&gt;
&lt;b&gt;[login_proc.asp]&lt;/b&gt;
&lt;xmp class=code&gt;
&lt;%
    dim req_id, req_pw
    dim retVal
    dim objLogin
    
    req_id  = Request(&quot;id&quot;)
    req_pw  = Request(&quot;pw&quot;)

    Set objLogin = Server.CreateObject(&quot;Mungchung.clsLogin&quot;)
    retVal = objLogin.doLogin(req_id, req_pw)
    
    Select Case retVal
        Case 0
            Response.Write &quot;알수 없는 오류 발생&quot;
        Case 1
            Response.Write &quot;존재하지 않는 아이디 입니다.&quot;
        Case 2
            Response.Write &quot;비밀번호가 일치하지 않습니다&quot;
        Case 3
            Response.Write &quot;로그인 성공!&quot; &amp; &quot;&lt;br&gt;&quot;
            Response.Write &quot;사용자 고유키값 : &quot; &amp; objLogin.getUserIdx &amp; &quot;&lt;br&gt;&quot;
            Response.Write &quot;사용자 이름 : &quot; &amp; objLogin.getUserName &amp; &quot;&lt;br&gt;&quot;
    End Select
    
    Set objLogin = nothing
%&gt;
&lt;/xmp&gt;

&lt;p&gt;id, pw를 파라미터로 일단 가져오고 위에서 생성한 dll 모듈을 호출한다.&lt;/p&gt;
&lt;xmp class=code&gt;
    Set objLogin = Server.CreateObject(&quot;Mungchung.clsLogin&quot;)
&lt;/xmp&gt;

&lt;p&gt;
내 무식한 머리로 처음엔 이해 못했는데 이 Mungchung가 위에서 만든 dll의 프로젝트 명칭이되고 clsLogin은 클래스 명이 된다.
(어리고 어리던시절 이걸 몰라서 엄청 고생했다는;;;)
&lt;/p&gt;
&lt;p&gt;그 다음은 doLogn메서드에 아이디와 비밀번호를 줘서 실행시켜서 그 반환값을 retVal에 저장시켰다.
반환값이 0이면 뭔가 오류가 발생한것으로써 뭔진 나도 모른다. -_- 어떠한 이유에서 오류가 난것일것이다.
그리고 1 일경운 아이디 없는경우 2일경운 비밀번호 틀린경우 3일경우는 로그인
그래서 로그인을 하면 objLogin.getUserIdx로 사용자 키값을 얻어오가 objLogin.getUserName로 사용자의 이름을 얻어온다.
마지막엔 Set objLogin = nothing 해서 자원을 해제한다.&lt;/p&gt;


&lt;p&gt;&lt;a name=&quot;c&quot; class=&quot;name&quot;&gt;3. 효과적인 dll 디버깅 방법&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;
자! 여기까지 별로 어렵지 않았다. 그러나 직접 이걸 응용해서 새로운것 만드려고 하면 굉장히 괴로워진다.
일단 괴로운게 디버깅이다. 위에서 생성한 dll모듈이 제대로 동작하는지 보려면 어떻게 해야할까?
&lt;/p&gt;

&lt;p&gt;
내 경우 잘 못하던 시절에 dll에서 하나 고치고 컴파일 해서 regsvr32로 등록한후에 웹페이지에서 실행해보고
오류나면 다시 dll수정해서 컴파일하고 웹에서 실행해보고 했는데 이럴경우 dll로 컴파일 할때 &quot;사용권한 없습니다&quot;
라고 나오는 경우가 있었다. 이 사용권한 오류는 dll을 등록해제했더라도 웹페이지에서 일단 한번 실행을 해두었기 때문에
가끔 그 asp.dll이 그 모듈을 놓지 못하는 경우때문에 생긴다. 
&lt;/p&gt;

&lt;p&gt;
이때에는 대개 2가지 방법으로 처리하곤 했다. 한가지는 조용히 dll파일명을 mungchung1.dll로 바꿔서 
컴파일 하던가 아니면 기존 등록된 dll파일 해제한후에 재부팅해서 그 파일 지우고 다시 컴파일 해서 등록했다.
첫번째로 파일이름 바꾼 방법은 하도 그러다 보니 mungchung23.dll까지 나오는 경우가 생겨서 도대체가 뭐가 뭐가 뭔지 모르는 경우가되버리고
두번째 방법은 재부팅을 너무 해서 기다리느라 지쳐버리고 -_-
&lt;/p&gt;

&lt;p&gt;
재부팅도 안하고 파일명도 바꾸기 싫다면 아래 방법처럼 하면 된다.
관리도구의 서비스항목으로 가면 되는데 마우스 클릭클릭 귀찮으므로 [내컴퓨터]에서 마우스 오른쪽 버튼 누른후에 &quot;관리(G)&quot;를 클릭하자
아래 이미지처럼 서비스 항목을 간 후에 거기서 IIS Admin 항목을 선택한후에 &quot;중지&quot; 후에 &quot;시작&quot;을 다시 해준다.
이렇게 하면 웹서비스가 죽어있는데 웹서비스를 다시 시작해준다. 
&lt;/p&gt;
&lt;p&gt;&lt;img src=/mianamssi/articles/img/dlllogin/4.gif&gt;&lt;/p&gt;
&lt;p&gt;이러고나서 다시 mungchung.dll로 컴파일 하면 &quot;사용권한 없습니다&quot; 오류 안뜬다.
이방법도 좀 귀찮긴 한데...개인적인 생각으론 파일명 바꾸기나 재부팅하기보단 나은듯 싶다 -_-
&lt;/p&gt;


&lt;p&gt;&lt;a name=&quot;d&quot; class=&quot;name&quot;&gt;4. Visual Studio에서 dll 디버깅하기&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;사실 가장 좋은 방법은 애초에 dll모듈을 잘 만들어서 위와 같은 방법으로 재컴파일을 수를 줄이는거다.
즉 실행환경을 asp로 하지 말고 VB로 하면 된다. VB에서 dll모듈을 충분히 테스트 하고 asp에서 이용한다면
위와 같은 귀찮은 일을 할 필요 없다.
&lt;/p&gt;

&lt;p&gt;
지금까지 만든 모듈을 VB에서 이용해 보자
&lt;/p&gt;
&lt;p&gt;
1. [새프로젝트]에서 &quot;표준EXE&quot;를 선택한다.&lt;br&gt;
2. [프로젝트]-[참조] 에서 &quot;Microsoft ActiveX Data Objects 2.x Library&quot;을 참조시킨다.&lt;br&gt;
3. 간단하게 커맨드버튼 하나 얹어 놓는다.&lt;br&gt;
4. 아래 이미지처럼 클래스 모듈 하나 추가한후에 그 클래스 모듈 이름을 clsLogin으로 한다.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img src=/mianamssi/articles/img/dlllogin/5.gif&gt;&lt;br&gt;
5. 위의 clsLogin 코드를 여기서 생성한 clsLogin에 붙여넣는다.&lt;br&gt;
5. 커맨트 버튼에 아래 소스 추가한다.&lt;br&gt;
&lt;/p&gt;
&lt;xmp class=code&gt;
Private Sub Command1_Click()
    Dim objLogin As clsLogin
    Set objLogin = New clsLogin
    MsgBox objLogin.doLogin(&quot;test1&quot;, &quot;1&quot;)
End Sub
&lt;/xmp&gt;

&lt;p&gt;
이 커맨드 버튼 누르면 간단하게 doLogin메서드 실행한다. 요런식으로 해서 혹 clsLogin모듈에 오류가 생기면 이 Visual Studio가
아주 친절하게 에러난곳 노랭이로 칠해주니 훨씬더 디버깅하기 편해진다.
이런식으로 exe파일에서 모듈을 이용하는 방식으로 테스트 해가면서 모듈을 만든후 이용하면된다.
이 테스트한 파일도 첨부파일 다운받아보면 ext_test란 폴더안에 있다. 참고하면된다.
&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;e&quot; class=&quot;name&quot;&gt;5. dll 배포&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
주의해야할점 또 한가지는 이 dll을 만들었다면 서버에 등록할때이다. 이 dll을 개발한 PC는 스튜디오가 설치되어 있기 때문에
오류날리가 없지만 실제 서버는 스튜디오 설치가 안되어 있고 꼭 필요한 프로그램만 설치되어있는 경우가 많다.
그래서 보통 VB로 만든 프로그램 서버에서 곧바로 이용하면 오류나는 경우가 종종있다.
왜냐면 VB는 VB Virtual Machine가 필요한데 그 관련 파일이 몇가지 된다. 이 파일들은 VB 배포마법사를 통해서 설치파일로 만들면
자동으로 포함되게 된다. 그래서 위에서 생성한 dll파일을 배포마법사를 통해서 설치파일로 만든후에 서버에서 그 설치파일로 설치를 하면 된다.
(왠만하면 mungchung.dll파일을 서버로 가지고 간후에 바로 regsvr32 mungchung.dll하지 말자..대개 서버에는 VB버쳐머신이 설치안된경우가 많다)
아! 꼭 스튜디오 이용하면 sp6으로 업데이트 해줘라. sp6을 하면 VB버쳐머신이 조금 틀려진다.
&lt;/p&gt;
&lt;p&gt;
지금이야 그냥 간단히 몇줄로 dll을 배포마법사를 통해서 배포하라고 말하지만 요것때문에 진짜 고생했던 적이 한두번이 아니다.
간단한 개념인데도 자꾸 까먹어서 오류날때마다 &apos;왜 날까 왜 날까&apos; 고민한적이 한두번이 아니다 -_-
&lt;/p&gt;


&lt;p&gt;
처음 적을때는 뭔가 대단한 경험을 적을것처럼했는데 역시나 적고보니 별내용 없다. -_-
귀찮아서 이미지캡쳐도 많이 안했다. -_-; 그냥 그러려니하고 보시길 -_-
&lt;/p&gt;&lt;/div&gt;</content>
                  
   </entry>
</feed> 

