언어에 대한 차이점

Visual Basic .NET은 .NET Framework를 활용하도록 고안되었기 때문에 많은 부분에서 이전 언어 버전과의 호환성이 유지되지 않습니다. 다음은 Visual Basic .NET에서 Visual Basic 언어로 변경되는 사항 중 일부 목록입니다. 자세한 내용은 Visual Basic 베테랑을 위한 Visual Basic .NET 소개를 참조하십시오.

  • 최신   바인딩.VBA 및 Visual Basic .NET은 최신 바인딩을 지원합니다. 그러나 이전에 바인딩된 개체를 사용하면 코드를 더욱 쉽게 읽고 유지 관리하고 IntelliSense를 사용할 수 있습니다. Visual Basic .NET에서는 이전 바인딩을 강제 적용하고 데이터를 잃을 수 있는 암시적인 변환을 방지하는 Option Strict On 문이 도입되었습니다. 컴파일러 기본값은 Option Strict Off입니다. 이를 위한 중요한 이유 중 하나는 Office 개체의 많은 메서드와 속성이 Object 형식을 반환하므로 다음 예제에 나오는 것처럼 개체를 정확한 형식으로 명시적으로 변환해야 하기 때문입니다.

    ' Using Ctype to convert the Object.returned by Sheet1 to a Worksheet.
    MsgBox(CType(ThisWorkbook.Worksheets("Sheet1"), Excel.Worksheet).Name)
  • 변수   선언 VBA에서는 Option Explicit 문을 사용하여 명시적인 변수 선언을 강제 적용할 수 있습니다. 또한 VBA IDE 옵션에서 변수 선언 요구 확인란을 선택하여 이 문을 자동으로 설정할 수도 있습니다. 이 확인란은 기본적으로는 선택되어 있지 않습니다. 암시적으로 선언된 모든 변수는 Variant 형식입니다.

    Visual Basic .NET 컴파일러는 명시적인 선언을 강제 적용하므로 모든 변수를 선언해야 합니다. Option Explicit Off 문을 사용하여 이 설정을 재정의할 수 있으며, 암시적으로 선언된 모든 변수는 Object 형식입니다. Visual Basic .NET에서는 Variant 데이터 형식이 더 이상 지원되지 않고 자동으로 Object 데이터 형식으로 변환되기 때문에, VBA에서 Visual Basic .NET으로 코드를 복사하거나 붙여넣을 때 이러한 점을 고려해야 합니다. 프로젝트에서 선언된 모든 변수를 명시적으로 입력해야 합니다.

  • 기본   속성 Visual Basic .NET에서는 해당 속성이 인수를 취하는 경우에만 기본 속성이 지원됩니다. VBA에서는 기본 속성을 제거함으로써 코드를 입력할 때 바로 가기를 사용할 수 있습니다. 예:

    ActiveDocument.Tables(1).Cell(1, 1).Range = "Name" 

    이 코드를 Visual Basic .NET으로 변환하려면 Range 개체의 기본 속성(Text)을 입력해야 합니다.

    ThisApplication.ActiveDocument.Tables(1).Cell(1, 1).Range.Text = "Name" 

    Tables 개체의 기본 속성(Item)은 인덱스 매개 변수를 취하지 않기 때문에 필요하지 않습니다. 그러나 모든 기본 속성을 포함하면 코드를 더욱 읽기 쉽게 만들 수 있습니다.

    ThisApplication.ActiveDocment.Tables.Item(1).Cell(1, 1).Range.Text _ = "Name" 
  • ByVal , ByRef 매개   변수 .VBA에서는 매개 변수가 기본적으로 참조로 전달되며, Visual Basic .NET에서는 매개 변수가 기본적으로 값으로 전달됩니다. 코드를 Visual Basic .NET으로 변환하려고 준비할 때, 모든 메서드가 매개 변수를 참조로 전달할 지 아니면 값으로 전달할 지의 여부를 명시적으로 정의하는지 확인하고 싶은 경우가 있을 것입니다. 정의되지 않은 매개 변수를 사용하여 Visual Studio .NET IDE에 코드를 붙여 넣으면 자동으로 ByVal가 목록의 각 매개 변수에 추가됩니다.

  • 열거 .Visual Basic. NET에서는 열거 상수가 정규화되어야 합니다. VBA 코드를 변환할 때 Word 및 Excel 상수에 모두 정규화된 열거 이름을 추가해야 합니다. 예를 들어, Word VBA에서 검색을 수행하는 경우 wd 상수를 사용하여 Selection 또는 Range의 FindWrap 값을 지정합니다. wdFindStop, wdFindAsk, wdFindContinue의 세 가지 옵션이 제공됩니다. VBA에서는 열거가 프로젝트에 대해 글로벌 특성을 띠므로 상수를 할당하기만 하면 됩니다.

    Selection.Find.Wrap = wdFindContinue 

    Visual Basic .NET에서는 다음과 같이 열거 이름을 사용하여 상수를 정규화해야 합니다.

    ThisApplication.Selection.Find.Wrap = Word.WdFindWrap.wdFindContinue 

    이렇게 하려면 추가 입력이 상당히 많이 필요한 것처럼 보이지만, Visual Studio .NET의 IntelliSense 기능을 사용하면 정규화된 상수를 찾아 입력하는 작업이 비교적 쉽고 코드를 더욱 읽기 쉽게 만들 수 있습니다. 이미 상수 이름에 익숙한 경우라면 해당 열거 이름이 상수 이름과 거의 일치한다는 사실을 알 수 있습니다. 위의 경우에는 모두 wdFind를 포함하고 있습니다. 사용 가능한 열거를 탐색하려면 Word.Wd를 입력하고 IntelliSense 드롭다운 목록에서 사용 가능한 항목을 스크롤합니다(Excel에 대해 사용할 수 있는 열거 목록을 스크롤하려면 Excel.XL을 입력합니다.)

  • 0    아닌   값의   배열 VBA에서는 배열 차원의 기본 하한값은 0입니다. Option Base를 사용하면 이 값을 1로 바꿀 수 있습니다. Visual Basic .NET에서는 Option Base 문이 지원되지 않으며 모든 배열 차원의 하한값은 0이어야 합니다. 또한 배열 선언으로 ReDim을 사용할 수 없습니다. Visual Basic .NET에서 Office 컬렉션을 사용할 때 유의할 사항 중 하나는 Office 컬렉션의 배열 하한값은 대부분 1부터 시작한다는 점입니다.

  • 메서드   호출      괄호   사용 VBA에서는 서브루틴을 호출할 때, 괄호가 선택 사항인 경우와 필수인 경우를 기억하는 것은 어렵습니다. Visual Basic .NET에서는 메서드 호출에서 매개 변수를 전달하는 경우에 괄호가 필수입니다.

  • Set 키워드 VBA에서 개체 할당과 개체의 기본 속성 할당을 구분하기 위해서는 Set 키워드가 필수입니다. Visual Basic .NET에서는 기본 속성이 지원되지 않기 때문에 Set 키워드가 필요하지 않으며 더 이상 지원되지 않습니다. 다음 예제는 이러한 변경 사항을 보여줍니다.

    ' VBA
    Dim mySelection as Selection
    Dim myOtherSelection as String
    Set mySelection = Selection
    myOtherSelection = Selection
    ' Visual Basic .NET
    Dim mySelection As Word.Selection
    Dim myOtherSelection As String
    mySelection = ThisApplication.Selection
    myOtherSelection = ThisApplication.Selection.Text
  • 데이터   액세스 Microsoft Visual Basic .NET에서는 데이터 액세스 개체(DAO) 또는 원격 데이터 개체(RDO) 데이터 원본에 대해 데이터 바인딩이 지원되지 않습니다. ActiveX 데이터 개체(ADO) 데이터 바인딩은 이전 버전과의 호환성을 위해 지원되지만 ADO.NET으로 변환하고 싶은 경우도 있을 것입니다. 자세한 내용은 ADO.NET과 ADO 비교를 참조하십시오.

  • UserForms  Windows Forms    변환 VBA UserForms는 Visual Studio .NET으로 복사하거나 가져올 수 없습니다. 대부분의 경우 사용자의 폼을 Windows Forms로 다시 만들어야 합니다. VBA에서 폼을 만들 때 끌어서 놓기 컨트롤은 일관되게 사용되지만 Windows Form 컨트롤의 이벤트 처리기는 다르게 처리됩니다. 다음과 같은 여러 가지 새로운 기능을 사용하면 폼을 이전보다 더욱 쉽게 만들 수 있습니다.

    • " 컨트롤 고정이 가능하므로 사용자가 폼 크기를 변경하면 컨트롤 크기가 자동으로 변경되고 컨트롤 배치가 알맞게 새로 조정됩니다.

    • " Windows Forms에서 탭 순서 설정이 훨씬 쉬워졌습니다. 보기 메뉴에서 탭 순서를 클릭하여 탭 순서 지정 기능을 활성화할 수 있습니다. 그런 다음 각 컨트롤을 원하는 순서대로 클릭하기만 하면 됩니다.

    • " VBA의 메뉴 생성 기능을 개선한 인라인 메뉴 생성 기능이 추가되었습니다.

    • " VBA에서는 폼을 vbModal 또는 vbModeless로 표시할 수 있습니다. Visual Basic .NET에서는 ShowDialog 메서드를 사용하여 폼을 모달로 표시하고, Show 메서드를 사용하여 폼을 비모달로 표시합니다. 그러나 폼을 비모달로 표시하고 Word나 Excel 문서를 클릭하면 폼이 배경으로 이동하므로 사용자가 혼동을 일으킬 수 있습니다.

    • " Visual Basic .NET에서는 데이터 입력 검사기, 공통 대화 상자, 하이퍼링크 레이블, 시스템 트레이 아이콘, 패널, 숫자 올리기/내리기(numeric-up/down), 즉석에서 디자인할 수 있는 트리 보기, 도움말 파일 링커, 도구 설명 확장선 등 다양한 새로운 폼 컨트롤도 사용할 수 있습니다.


https://msdn.microsoft.com/ko-kr/library/aa192490(v=office.11).aspx







-브라우저에서 입력한 정보는 request 객체에 담겨 서블릿으로 들어옴

-html형식으로 응답해줌

-서브릿은 html로 응답하기 위해 res객체의 write 객체에 넣어 보냄

-html 적은 부분을 nodejs는 render함수로 쉽게보냄





























































출처 : http://wanzargen.tistory.com/23?category=705682


이전에 자바 웹 프로젝트를 생성하는 것을 설명한 적이 있었당.


요것을 모르겠다면 이전 포스트 읽고오시길.


=>  2017/06/01 - [Programming/Lib, Tools] - Eclipse :: 이클립스에서 웹 애플리케이션(Web Application) 프로젝트 만들기



이번 포스트에서는 이클립스의 자바 웹 애플리케이션 구조 와  실무의 자바 웹 애플리케이션 구조  를 설명하고 어떻게 다른지 비교하면서


왜. 대체 왜 실무에서는 다른 프로젝트 폴더 구조를 사용하는지를 이야기하며 마무리하도록 하게따.



1. 이클립스 웹 애플리케이션 디렉토리 구조

$workspace/프로젝트명/build

/classes

/src

/WebContent

/META-INF

/WEB-INF

/lib


이거슨 이클립스의 자바 웹 애플리케이션 디렉토리 구조이다.

이전에 이클립스에서 웹 프로젝트를 만드는 방법을 소개했었는데, 그 2 가지 방법이 있었다. 
(이클립스의 다이나믹 웹 프로젝트를 만드는 방법과 gradle을 이용하는 방법.)

그 중, 손쉽게 만들 수 있는 이클립스 다이나믹 웹 프로젝트를 생성하게되면, 위와 같은 구조를 띈다.

그런데, 회사마다 다르겠지만. 이 구조는 잘 사용하지 않는다.


그렇담?? 뭐가 실무에서 많이 쓰이는데??

2. 실무의 웹 애플리케이션 디렉토리 구조 (=Maven 웹 프로젝트 구조)


실무에서는 대부분  메이븐의 웹 프로젝트 구조를 많이 쓴다.

개발을 돕는 툴들이 겁나게 많은데, 메이븐은 그 중 하나로, 사이트에 가보면 스스로를 이렇게 설명하고 있다.

Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project's build, reporting and documentation from a central piece of information.


비슷한게 Gradle이 요새는 뜨고 있는데 이와 관련된 내용은 다음에 제대로 포스팅 하는 것으로 하고. 

다시 본론으로 돌아와, 이게 그 폴더 구조이다.

$workspace/프로젝트명

/src

/main

/java

/resources

/webapp(=WebContent)

/WEB-INF

/test

/java

/resources

/bin



 

<디렉토리 설명>


-  src : 프로그램 소스 파일을 두는 곳


- main/java : 자바 소스 파일(.java파일)을 두는 곳


- main/resources : 프로그램을 실행할 때 사용하는 설정 파일(.properties, .xml 등)을 두는 곳


- main/webapp : HTML, CSS, JavaScript, GIF 등 정적 웹 자원을 두는 곳.

                   (JSP파일도 여기에 둠)


- main/webapp/WEB-INF : 웹 애플리케이션 정보 파일을 두는 곳


- test : 코드를 테스트하는 소스 파일을 두는 곳


- test/java : 단위 테스트 관련 자바 소스 파일을 두는 곳


-bin : 소스코드가 컴파일된 *.class 파일, *properties파일, *xml파일 등



그런데 우리의 이클립스는 메이븐 폴더구조를 알아서 딱딱 만들어주지 않는다.


이클립스로 웹 플젝트를 암만 만들어봐야 지네 플젝 구조를 만들어줄 뿐. 몹쓸.



3. 현업에서 메이븐 폴더 구조를 자바 웹프로젝트 디렉토리 구조로 많이 사용하는 이유

사람마다, 회사마다 모두 다른 IDE를 사용한다.

어떤 사람은 이클립스를 쓰는데 또 어떤 사람은  인텔리제이를 쓰고.. 

그럼 프로젝트를 함께 개발한다고 할 때, 공유하기가 매우 불편하다.


즉, 특정 IDE폴더구조를 사용하게 되면 공유하기가 불편하다. 


저사람과 내가 사용하는 폴더구조가 다르면, 어떤 파일은 여기에, 또 어떤 파일은 저기에 내가 직접 한땀한땀 복붙해줘야 하며

뭐 하나 잘못하면 잘 돌아가야 할 프로젝트가 안 돌아가는 대참사가 일어나게 마련.


이 때문에 전 세계 공통으로 사용하는 폴더구조가 있는데 그게  Maven 폴더 구조다.

이게 국제적으로 모든 개발자가 가장 많이 사용하는 폴더 구조인거다.


그리고 다른 사람과 공유할 일이 생기면, src폴더만 공유하면 된다.



그럼 이클립스에서 이 메이븐 폴더 구조를 사용하려면??


이클립스에서 메이븐 폴더 구조를 만들어주려면 src 폴더와 그 밑의 폴더들을 모두 직접 만들어주면 된다.


참고로 이클립스는 컴파일이 되면서 자동으로 bin 폴더를 생성한 후 그 곳에 class파일을 두니까 굳이 bin폴더를 만들어줄 필요는 없다.


src 폴더 구조만 만들어준 후, 이전 포스트에서 소개한 방법을 응용해주면 되시겠다.



끄읏-.

▶ JAVA 형변환 정리


[Int 형을 String 형으로]

int int_val;

String myStr = Integer.toString(int_val);

String str=""+i;



[Double 형을 String 형으로]

double double;

String str = Double.toString(double);



[long 형을 String 형으로]

long l;

String str = Long.toString(l);



[float 형을 String 형으로]

float f;

String str = Float.toString(f);



[String 형을 Int 형으로]

String str;

int i = Integer.parseInt(str);

int i = Integer.valueOf(str).intValue();



[char 형을 String 형으로]

char c;

Character.toString(c);



[String 형을 double 형으로]

String str;

double d = Double.valueOf(str).doubleValue();

double d = Double.valueOf(str);



[String 형을 long 형으로]

String str;

long l = Long.valueOf(str).longValue();

long l = Long.parseLong(str);



[String 형을 float 형으로]

String str;

float f = Float.valueOf(str).floatValue();

float f = Float.parseFloat(str);



[2진수 문자열 s를 10진수로]

int i = Integer.parseInt(s, 2);

[String 문자열을 char 문자 배열로] String a = "안냐세요"; char[] as = a.toCharArray(); //char[] as = {"안", "냐", "세", "요"} for(char i:as){System.out.println(i);} >>>안\n냐\n세\n요 char은 하나의 문자만 가지기 때문에, String line = "나는 배가 고프다"; 와 같은 문장을 띄어쓰기 단위로 저장하고 싶을 때는 split 함수를 사용하면 된다.

[char 문자열을 int 형으로] int cnt = 1; char[] charray = ["1","2","3","4","5"]; for (char A: charray){cnt = cnt + Character.getNumericValue(A);} >>> 15

▶ 자바의 Math 클래스

자바에서 Math클래스는 숫자와 관련된 처리를 위한 메소드를 포함하고 있다심화로 들어가면 삼각함수 등 수학적인 내용도 많지만 가장 기본적인 메소드를 알아보자.이전에 프로젝트를 진행하며 간단한 게임을 제작했는데 그때 몬스터의 등장 부분에 Math.random() 값을 많이 사용했던 경험이 있다.Math class is in the java.lang package, which is imported by default. (It's the only package imported by default, I believe.) 또한 클래스명으로 메서드를 부를 수 있기때문에 abs, ceil, floor 등은 math 클래스의 정적메소드(static method)이다.


Math 클래스 정리

import ​java.lang.Math → 디폴트 임폴트 내용

※Math.(함수) 의 형식으로 Math 클래스의 메서드들이 사용되는 것으로 보아, 이것들은 정적메서드(static)메서드들이다.

Math.abs(double a) : 절대값

Math.ceil(double a) : 값올림

Math.floor( double a): 값내림

Math.round (double a): 반올림

Math.max(double a, double a): 큰 쪽 반환

Math.min(double a, double b) : 작은 값 반환

Math.pow(double a, double b) : 제곱

Math.random() : 0~1사이 값을 랜덤으로 반환


random함수는 0~1까지의 수만 반환하기 때문에, 1에서 10사이의 정수를 랜덤으로 뽑아내기 위해서는 아래와 같은 과정이 필요하다.

 

for (int i = 1; i <= 20; i++) {

int n = (int) (Math.random() * 10) + 1;

System.out.println(n);

}

 

▶ 배열을 순서대로 정렬해주는 array 클래스의 sort 메서드 /리스트를 순서대로 정렬해주는 Collections 클래스의 sort 메서드 also 역순 정리
형태 : Arrays.sort(배열)     input : 배열     output : 배열

형태 : Collections.sort(리스트)     input : 리스트     output : 리스트

 


 


▶ split

형태 : 문자열.split("스플릿기준")   input : 문자열   output : 배열

 

 java.lang은 디폴트로 제공되는 import 이므로 굳이 표시할 필요없다.


※String의 split함수는 정규식을 이용할 수 있다. 따라서 |나 .을 기준으로 split을 사용할 때는 조금 다른 사용법이 필요하다.

예를 들어 String A = "12.33.2.52"; 를 스플릿 하고 싶다면

A.split(".");                 → X
A.split("\\.");
         → O

이스케이프문자 \를 이용해, 정규식이 아님을 알려줘야하는 것이다.

 

▶ 리스트 내에서 최소값, 최대값 구하기

형태 : Collections.max/min(list)    input : 리스트   output : 리스트내 최대/최소값

ArrayList와 Collections 클래스를 활용하여, 리스트내의 최대, 최소값을 구할 수 있다. 
Collections.max() 최대값, Collections.min() 최소값

import java.util.ArrayList;
import java.util.Collections;

ArrayList<Integer> list = new ArrayList<Integer>();

list.add(12);
list.add(39);
list.add(8);
list.add(10);

//최대값
Integer i = Collections.max(list);
System.out.println(i);                     //39 출력

//최소값
Integer i2 = Collections.min(list);
System.out.println(i2);                   //8 출력

▶ 클래스로 타입을 선언하는 것의 의미

Student 클래스가 존재 한다고 하자.int jackson와 같이 기본타입으로 선언된 경우는jackson 변수가 숫자를 갖을 수 있다 라는 명확한 의미를 가지고 있는데 , Student jackson와 같은 경우처럼 Student 클래스로 jackson이라는 변수의 타입을 정의한다는 것은 어떤 의미를 갖는 것일까? 그러기 위해선 먼저 클래스의 정의 부터 살펴 보아야 한다. 클래스란 int jackson, String daniel 과 같은 상태 그리고 동작을 표현하는 메서드가 모여있는 집합이다. 따라서, Student jackson으로 변수타입을 선언하면 Student의 상태와 동작을 표현할 수 있는 변수에 접근할 수 있는 권한 얻게 된 것이다.(jackson.varible, jackson.method()로 Student의 내용을 가져다 쓸 수 있음) 또한 그러한 선언으로 인해 다른 클래스에서 Counter 클래스의 기능을 가져와서 사용할 수도 있게 된다.

쉬운 예로 다음과 같은 것이 있다.  

학생이라면 이름이 필요하고 학번도 필요하고 기타 신상 정보도 필요하겠죠?

그걸 학생이라는 이름의 클래스로 선언해서 하위 멤버 변수들을 상황에 맞게 사용하는 거죠

정말 간단하게만 설명 드리자면

studentname1. studentname2......
studentid1, studentid2.....
학생이 가져야 할 정보가 100개라고 생각해 보세요 그럼 배열을 쓰더라도 100개의 배열을 선언해야겠죠?
그런데 student라는 클래스를 만들면 student[100]이라고 한번만 선언해도
id, name같은 모든 인자를 학생별로 분리해서 쓸수 있으니까요




▶ length 와 .length() 의 차이점


<tbodytr style="color: rgb(85, 85, 85); font-family: Tahoma, 굴림, sans-serif; font-size: 12px; text-align: justify; white-space: normal; background-color: rgb(255, 255, 255);"></tbodytr>

 .length.length()
형태변수메서드
input배열문자열
output배열의 갯수문자열의 길이


▶ ArrayList객체가 취급하는 값

ArrayList 객체는 레퍼런스 값만 담을 수 있기때문에 프리머티브는 파라미터로 설정할 수 없다.


ArrayList <int> = new ArrayList<int>(10); (X) ArrayList <Integer> = new ArrayList<Integer>(10); (O)

▶ String의 값을 비교하는 equal 메서드

다음의 예를 보자.

String a = "hello";
String b = "java";
String c = "hello";
System.out.println(a.equals(b)); // false
System.out.println(a.equals(c)); // true

문자열 a 와 문자열 b 는 "hello"와 "java"로 서로 같지 않다. 따라서 equals 메소드 호출 시 false 를 리턴한다. 문자열 a 와 문자열 c 는 "hello"와 "hello"로 서로 같다. 따라서 true 를 리턴한다.

문자열의 값을 비교할때는 반드시 equals 를 사용해야 한다. == 연산자를 사용할 경우 다음과 같은 경우가 발생할 수 있다.

String a = "hello";
String b = "hello";
String c = new String("hello");
System.out.println(a.equals(b));
System.out.println(a==b);

문자열 a와 b와 c는 모두 "hello"로 같은 값이지만 참조하는 위치가 다르다. a와 b는 heap 메모리 내의 String pool에 저장된 hello의 위치를 같이 참조하기 때문에 같지만, c는 heap 메모리 내에 독립적인 메모리 주소값을 갖기 때문에 참조하는 위치가 a,b와는 다르다.   == 은 두개의 자료형이 동일한 객체인지를 판별할 때 사용하는 연산자이기 때문에 false를 리턴하게 되는 것이다.


▶ if조건판단문 내에서 쓰이는 and(&&), or(||), not(!)

 조건 판단에 쓰이는 것으로 and, or, not이란 것이 있다. 파이썬과 다르므로 주의할 것
 

▶ 주어지는 수에 의해 변수가 계속 변해 갈때의 프로그래밍

import java.util.Scanner; public class practice { public static void main(String[] args) { int[] card = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}; int[] arg = new int[2]; // arg = {int1,int2} Scanner scan = new Scanner(System.in); for(int i = 0; i < 10; i++){ arg[0] = scan.nextInt(); arg[1] = scan.nextInt(); System.out.println(arg[0] + " " +arg[1]); card = reverse_card(arg[0], arg[1], card); } for(int i = 0; i < 20; i++) System.out.print(card[i]+ " "); } private static int[] reverse_card(int i, int j, int[] card) { // i=6, j=10 int[] arrangment = new int[2]; for(;i <= j;i++,j--){ //i와 j의 값은 주어지는 값이기 때문에 비워둔다. arrangment[0] = card[i-1]; //arrangment = {6,10} arrangment[1] = card[j-1]; card[i-1] = arrangment[1]; //card = {1,2,3,4,5,"10,9,8,7,6",11,12,13,14,15,16,17,18,19,20}; card[j-1] = arrangment[0]; } return card; } }



▶ 배열에서의 내용물 비교


array1.equals(array2)는 array1 == array2 이 완전히 동일하다는 의미로, 완전히 동일하다는 것은 두 배열이 포함하는 내용을 넘어서 같은 "객체"인지를 비교하는 것이다. 따라서 단순히 내용물만 비교하기 위해서는 다른 메서드를 사용해야 하는데, Arrays.equals(array1,array2)는 두 배열의 내용물만이 같은지를 비교한다.

import java.util.*;
public class practice {
        public static void main(String[] args) {
               int [] card1 = {1,2,3};
               int [] card2 = {1,2,3};

               if(card1.equals(card2)){System.out.println("객체일치");}
               else
{System.out.println("객체불일치");}

               if(Arrays.equals(card1, card2)){System.out.println("내용물일치");}
               else
{System.out.println("내용물불일치");}
        }
}

>>>
객체불일치
내용물일치


▶ 하나의 문제에 여러가지의 풀이법을 생각해보기

 하나의 문제에 대해 여러가지 풀이법을 생각해 보는 활동은 자기자신이 일반적으로 구상하는 알고리즘을 벗어나 창의적인 알고리즘으로 발돋움 할 수 있는 기회를 제공해준다. 이는 프로그래밍 뿐만아니라 일반적인 문제풀이에도 통하는 이야기이다.


▶ 리스트에서 remove를 사용할 시에 주의사항

 리스트의 remove함수는 기존 리스트의 모양을 변형시켜버린다는 점에서 사용시 주의를 요한다.  

String [] array_s1 = s1.split("");  // {"c","a","t","s"}

String [] array_s2 = s2.split("");  // {"c","s","t"}



ArrayList <String> list_s1 = new ArrayList <String>(); 

ArrayList <String> list_s2 = new ArrayList <String>();

for (String i : array_s1){list_s1.add(i);}  //list_s1 = [c, a, t,s]

for (String l : array_s2){list_s2.add(l);}  //list_s2 = [c, s, t]

ArrayList <Integer> filter = new ArrayList <Integer>();

if (list_s1.size() > list_s2.size()){  

for (int i =0;i<list_s1.size();i++){  //list_s1 = [c, a, t, s]

list_s1.remove(i);  //리스트 요소제거 -> 원형훼손

if (list_s1.equals(list_s2)){filter.add(1);list_s1.add(i,array_s1[i]);}  //리스트 요소 재추가 = 원형유지

else {filter.add(0);list_s1.add(i,array_s1[i]);continue;}

}

if (filter.contains(1)){System.out.println("true");}

else{System.out.println("false");}

else{

for (int i =0;i<list_s2.size();i++){

list_s2.remove(i);  //리스트 요소제거 -> 원형훼손

if (list_s2.equals(list_s1)){filter.add(1);list_s2.add(i,array_s2[i]);}   //리스트 요소 재추가 = 원형유지

else {filter.add(0);list_s2.add(i,array_s2[i]);continue;}

}

if (filter.contains(1)){System.out.println("true");}

else{System.out.println("false");}

}

 위의 예는 기존의 문자에서 단 하나의 문자만이 추가 되었을 때, 두개의 문자를 같은 것으로 판별하는 프로그래밍이다.(예를 들어 s1 = "cats", s2 = "cat"라면 두 문자는 같다.
 list_s1=[c,a,t,s]이고 이 리스트의 원형을 유지해가면서, 코딩이 진행되어야 하는데, remove를 쓰게 되면 remove가 작동할 때마다 list_s1의 요소들이 삭제되어 원형이 훼손되게 된다. 따라서, 위의 코딩에서는 제거된만큼 다시 추가해주는 작업을 진행했다. 이 외에도 파이썬의 경우, 제거되어야할 인덱싱만 제외하고 제거대상 요소 앞뒤의 요소들을 합치는 코딩도 있지만, 기본적으로 자바는 리스트나 배열의 더하기 기능을 제공하지 않기 때문에 불가능하다.

▶ print, println, printf
- System.out.print()
()안의 문장을 출력하고 커서가 그 줄에 위치하게 되므로 \n을 통해 직접 개행해야 한다.

- System.out.println()
()안의 내용을 출력하지만 커서를 다음 줄로 자동 개행 시킨다.

-System.out.printf()
파이썬의 문자열 포매팅과 비슷한 기능
 System.out.printf("오늘의 날씨는 %s 도 입니다", 13);
 System.out.printf("오늘의 날씨는 %s 도 이고 %d 요일 입니다", 13,"수");


▶ 리스트 중복 요소 제거
TreeSet을 이용해 리스트의 중복을 제거할 수 있다.
TreeSet <type> 트리셋리스트명 = new TreeSet<type> (중복 제거 대상 리스트);
 

import java.util.*;
public class practice {
     public static void main(String[] args){

             ArrayList <Integer> ugly_collections=new ArrayList <Integer>();

             ugly_collections.add(1);
             ugly_collections.add(1);
             ugly_collections.add(2);
             ugly_collections.add(2);
             ugly_collections.add(3);
             ugly_collections.add(4);
             TreeSet <Integer> distinctdata = new TreeSet<Integer>(ugly_collections);
             System.out.println(distinctdata);
             }
    }

▶ 클래스 변수 선언이 가지는 의미와 다형성의 이해
 ⓐ클래스 객체주소를 참조할 수 있는 공간을 마련한다 
ⓑ클래수 변수 선언에 의해 선언된 변수는 클래스 객체주소의 각각의 요소에 접근할 수 있는 권한을 가진다. 
 

interface Shape{

public static final double Pi = 3.14;

public abstract double calculateArea();

public abstract double calculatePerimeter();


}


class Rectangle implements Shape{

private double length;

private double breadth;

//constructor

public Rectangle(double length, double breadth){

this.length = length;

this.breadth = breadth;

}


public void Rectanglecall(){

System.out.println("I'm Rectangle");

}

//inheritance override

public double calculateArea(){

return length*breadth;

}

//inheritance override

public double calculatePerimeter(){

return 2*(length*breadth);

}

}

Shape s 의 shape 타입의 경우, s는 double Pi = 3.14/ double calculateArea() / double calculatePerimeter()의 3부분에 접근할 수 있는 권한을 가진다. Rectangle r의 Rectangle 타입의 경우, r은 상속한 부분 : double Pi = 3.14/ double calculateArea() / double calculatePerimeter()  Rectagle타입의 고유부분 : double length/ double breadth / Rectangle(double length, double breadth){}; / void Rectanglecall(){}; 의 7부분에 접근할 수 있는 권한을 가진다. 

때문에, Shape s = new Rectangle(); 의 다형성을 구현해도 s는 double length/ double breadth / void Rectanglecall(){}; 에는 접근권한이 없기때문에 구현할 수 없다. (Rectangle은 생성자이기 때문에 객체 생성시 자동으로 접근한다)  접근하고 싶다면 상향형변환을 통해 접근이 가능하다.

▶ 상속시 멤버변수의 접근제어자 관리의 중요성
 
메서드의 경우 조상 클래스의 메서드를 자손의 클래스에서 오버라이딩한 경우에도 참조변수의 타입에 관계없이 항상 실제 인스턴스의 메서드(오버라이딩된 메서드)가 호출되지만, 멤버변수의 경우 참조변수의 타입에 따라 달라진다. 자손클래스를 참조하여 조상클래스에 없는 멤버변수를 호출할 수 없은 것은 당연하고, 멤버변수가 조상 클래스와 자손 클래스에 중복으로 정의된 경우라 하더라도,  멤버변수를 호출시 자손클래스의 멤버변수가 아니라 조상클래스의 변수가 호출된다.

 따라서 상속시 멤버변수 상속에 의한 혼란을 피하기 위해, 애초에 자손클라스의 멤버변수를 private로 한정하고 메서드를 통해서 이니시에이팅 하는 경우가 많다.


package hellojava;



public class practice2{


//어트리부트(멤버변수, 인스턴스 변수) 는 private으로 설정

private String name;

private String employeeNo;

private int password;


//getter 와 setter 설정

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getEmployeeNo() {

return employeeNo;

}

public void setEmployeeNo(String employeeNo) {

this.employeeNo = employeeNo;

}

public int getPassword() {

return password;

}

public void setPassword(int password) {

this.password = password;

}


}

※How to make getter and setter ? 마우스 오른쪽 -> source -> generate getter and setter 



▶ 인터페이스의 다양한 접근제어자

기본적인 인터페이스의 접근제어자는 멤버변수의 경우 public final, 메서드의 경우 public abstract 이지만 그 외에도, public static, public default가 있다. 

interface Address {


String getStreet();

String getCity();


default String getAddress() {  // 인터페이스의 defaul, static 메서드는 {}중괄호 까지 포함한 완전한 메서드의 모습이다.

return getStreet() + ", " + getCity();

}


static String getCountry() {   // 인터페이스의 defaul, static 메서드는 {}중괄호 까지 포함한 완전한 메서드의 모습이다.

return ("India");

}

}


public class Letter implements Address {

private String street;

private String city;


public void Letter(String street, String city) {

this.street = street;

this.city = city;

}


@Override

public String getCity() {

return city;

}


@Override

public String getStreet() {

return street;

}


//인터페이스의 ​default String getAddress() ;와 static String getCountry() {}은 구현되지 않았다.

public static void main(String[] args) {

Letter letter = new Letter("1001 Lotus Panache", "Delhi");

System.out.println(letter.getAddress()); //슈퍼클래스의 상속처럼, '객체.메서드'의 형태로 사용한다.

System.out.println("Country " + Address.getCountry());//생성자의 경우 '인터페이스 이름. 메서드'로 사용한다.

       }

}


▶ 클래스에 대한 더 깊은 이해

지금까지 클래스에 대한 내용을 정리하면 다음과 같다.
Water w1= new Water ();

Water w2= new Water ();


( new Water () : 설계도, Water w1/Water w2 : Water라는 설계도로 만들어진 각각의 제품)


 Water 타입변수(클래스 타입의 변수) w는 2가지 기능을 갖는다. 

ⓐ Water 클래스의 주소값을 참조하여 클래스 전체를 저장해 두는 기능 

ⓑ Water 클래스의 각각의 멤버변수(필드), 메서드를 사용할 수 있는 권한 

ⓒ w1과 w2는 Water라는 동일한 클래스의 내용을 참조하고 있지만, 단지 참조하는 것일 뿐이므로 w1에 저장된 값과 w2에 저장된 값은 다른다.(w1과 w2는 독립성을 지닌 객체이다) ⓒ 변수 w은 Water 클래스 내부의  멤버변수와 메서드를 사용할 수 있는 권한만을 지니기 때문에, 그 이상의 멤버변수와 메서드를 가지고 있는 다른 클래스를 다형성으로 받았을때 본래 멤버변수와 메서드 이외의 부분은 구현할 수 없다.


class Water{

String water = "water";

public void water(){

System.out.println("water");

}

// public String toString(){

// return "water";

// }


}


public class practice{

public static void main(String[] args){

String Fire = "Fire";

Water w = new Water();  // Water타입 변수 w은 1.인스턴트 변수 water, 2. water메서드에 접근할 수 있는 권한을 부여받는다.

System.out.println(Fire);

System.out.println(w);            //    클래스 전체를 프린터

System.out.println(w.water);  // 변수 w을 통해 멤버 변수를 프린터

w.water();

}

}

>>>

Fire

hellojava.Water@1db9742    →    ★클래스 전체가 프린터된다!! 하지만 읽을 수는 없다.

water

water

>>>   toString을 구현했을 때의 결과값

Fire

water    →    클래스 전체의 프린트 내용이 String으로 명확해졌다.

water

water

▶ What is the difference between Collection and Collections in java?

This is one of the most confusing java interview question asked many a times to java freshers. Most of time, this question has been asked to java freshers to check their basic knowledge about the Java Collection Framework. This question seems confusing because both “Collection” and “Collections” look similar. Both are part of java collection framework, but both serve different purpose. Collection is a top level interface of java collection framework where as Collections is an utility class. In this article, we will discuss the differences between Collection and Collections in java.

<ins id="aswift_0_anchor" style="box-sizing: border-box; margin: 0px; padding: 0px; vertical-align: baseline; outline: 0px; background: 0px 0px transparent; border: none; text-decoration-line: none; display: block; height: 90px; position: relative; visibility: visible; width: 757px;">CollectionInterface :
Collection is a root level interface of the Java Collection Framework. Most of the classes in Java Collection Framework inherit from this interface. List, Set and Queue are main sub interfaces of this interface. JDK doesn’t provide any direct implementations of this interface. But, JDK provides direct implementations of it’s sub interfaces. ArrayList, Vector, HashSet, LinkedHashSet, PriorityQueue are some indirect implementations of Collection interface. Map interface, which is also a part of java collection framework, doesn’t inherit from Collection interface. Collection interface is a member of java.util package.</ins>




Collections Class:
Collections is an utility class in java.util package. It consists of only static methods which are used to operate on objects of type Collection. For example, it has the method to find the maximum element in a collection, it has the method to sort the collection, it has the method to search for a particular element in a collection. Below is the list of some important methods of Collections class.
Collections.max()This method returns maximum element in the specified collection.
Collections.min()This method returns minimum element in the given collection.
Collections.sort()This method sorts the specified collection.
Collections.shuffle()This method randomly shuffles the elements in the specified collection.
Collections.synchronizedCollection()This method returns synchronized collection backed by the specified collection.
Collections.binarySearch()This method searches the specified collection for the specified object using binary search algorithm.
Collections.disjoint()This method returns true if two specified collections have no elements in common.
Collections.copy()This method copies all elements from one collection to another collection.
Collections.reverse()This method reverses the order of elements in the specified collection.



▶ java collection framework에서 다형성을 빈번하게 사용하는 이유

 아래의 예에서 Set <String> placeSet = new HashSet<>();  와 같이 JCF의 클래스가 상위의 인터페이스를 다형성을 통해 참조시키는 경우를 빈번하게 볼 수 있다. List <String> list = new ArrayList<>();도 그 예 중하나다. 하위 클래스가 상위 인터페이스를 다형성을 통해 참조시키는 이유는, 상위 인터페이스로 변수를 선언하면 하위의 클래스를 실행할 때마다 일일이 새로운 변수를 선언할 필요가 없이 인터페이스의 변수 하나만으로 코딩을 전개할 수 있기 때문이다. 가령, Set인터페이스의 아래에는 HashSet과 SortedSet의 클래스가 있으며, Set <String> placeSet = new HashSet<>(); Set <String> placeSet = new SortedSet<>(); 과 같이 placeSet 변수로 HashSet과 SortedSet의 클래스를 모두 받아올 수 있어서 편리하다.


package hellojava;


import java.util.HashSet;

import java.util.Iterator;

import java.util.Set;


public class practice {

public static void main(String[] args) {

Set <String> placeSet = new HashSet<>();  

System.out.println(placeSet.add("Zoo"));  

System.out.println(placeSet.add("Park"));

System.out.println(placeSet.add("Museum"));

System.out.println("Output for Set Collection : ");


for (Iterator<String> iterator = placeSet.iterator(); iterator.hasNext();) {

System.out.println("Elements are : " + iterator.next());

}

}

}

▶ 자바이클립스 단축키모음

ctrl + O :클래스 내부의 클래스, 메서드 이름 및 구성확인

ctrl + t : 상속 인터페이스하는 클래스와의 클래스의 위계관계를 볼 수 있다.  
오브젝트. + ctrl + space : 오브젝트 클래스의 메서드확인

F3 :  메서드나 클래스의 원래 위치로 이동

F2 :  메서드나 클래스의 설명이 나옴
ctrl + shift + r : 이클립스내부의 class, xml, html 등의 파일을 검색할 수 있다.

ctrl + shift + o : import되지 않은 클래스를 자동으로 import 해준다.



▶ Package 가 다른 Class를 불러올 때는 Import package.class; 를 통해 calling 해야 사용할 수 있다.

▶ Static import

static import:It has function that static method or static field can be used

not declaring Class object


ex] Class Daseul has static head field argument.


in Sooyeon Class import static org.junit.Daseul.*; (*could call all static inside Daseul class)


25. 디버깅 단축키

F6 : 한줄 씩 디버깅

F7 : 이전 브레이크 포인트로 돌아가기

F8 : 다음 브레이크 포인트로 넘어가기

F11 : 디버깅 초기화



▶ 한 클래스 내의 한 함수에서 다른 함수를 부를 때는 객체 생성할 필요가 없다.


package com.java.ex4;


import java.util.ArrayList;


public class MyInfo {

private String name;

private double height;

private double weight;

private ArrayList<String> hobbys;

private BMICalculator bmiCalculator;


public void bmiCalculation(){

bmiCalculator.bmiCalculation(height, weight);

}

public void getInfo(){

System.out.println("name: " + name);

System.out.println("height: " + height);

System.out.println("weight: " + weight);

System.out.println("hobby: " + hobbys);

bmiCalculation();

}

▶ 자바의 설계에서의 팁 ★

다음의 자바 클래스 설계는 내가 구현하고자 하는 유저 인터페이스에서 부터 역으로 생각하여 클래스를 설계하는 팁이다.

1. 먼저 내가 구현하고자하는 인터페이스를 실제로 그려라.

2. 그 유저이터페이스에 필요한 변수가 무엇이며, 하나하나의 변수들이 어떠한 계산의 결과 아웃풋된 대상인지 생각하라.

3. 아웃풋을 유발한 논리적 구조를 클래스로 구현해라.

*클래스를 구현할 때는 다음과 같은 요소에 주의하라.

-하나의 클래스가 하나의 기능만을 가지고 있는가?(가령, 변수를 지정한다, 한 변수를 아웃풋한다.. 등등)

-발생할 수 있는 유지.보수들을 고려했을 때, 유지보수가 용이한가?

4. 역으로 생각한 마지막 단계는 인풋값이 들어가는 클래스이다.


5.클래스의 설계가 끝난 이후엔, 역순의 역 그러니까 순방향으로 생각하여 "인풋 - 알고리즘 - 아웃풋" 이 가능한지 검증한다.


▶ main메서드의 (String[] args)의 의미

cmd에서 자바를 시행하면 args에 값을 시스템 내부값으로 인풋할 수 있다.  이것이 존재하는 이유는 자바파일을 시행시킬 때 초기값을 전달할 수 있기 때문이다.  


//Test.java

public class Test{


public static void main(String[] args){

for(int i=1;i<10;i++){

for(int k=1;k<10;k++){

System.out.println(i+"*"+k+"="+i*k);

}

}

if(args.length != 0){

System.out.println(args[0]);

System.out.println(args[1]);

}

}

//cmd

javac Test.java
java  Test Hi Hello

▶ package의 이름은 단순한 파일명이 아니라, 디렉토리를 패싱해주는 역할을 한다.

Package com.java.ex 라 함은, .../com/java/ex의 의미이다.아래는 패키지가 설정되어 있는 java파일을 cmd에서 여는 방법이다.


C:\Users\daseul.kim\Desktop\JavaManuelTest\com\java\exha에 Test.java파일이 있고 현재 디렉토리는 C:\Users\daseul.kim\Desktop\JavaManuelTest라고 할때


[cmd]

C:\Users\daseul.kim\Desktop\JavaManuelTest>javac com/java/exha/Test.java


C:\Users\daseul.kim\Desktop\JavaManuelTest>java com.java.exha.Test

▶ 자바에서 중괄호{}는 라이프 사이클을 시작과 끝을 의미한다. 

 지금까지는 중괄호가 반드시 class, method, for, while, if문 뒤에만 쓰이는 줄 알았지만, 어디에도 올 수 있으며, 중괄호는 그 안에 포함된 변수의 라이프 사이클의 시작과 끝을 의미한다. 때문에 class 중괄호 이후에 오는 변수는 전역변수, 메소드 중괄호 이후에 오는 변수는 지역변수로 구분되는 것이다.


▶ try ~ catch문에서 가장 마지막 catch문은 Exception 예외를 처리해주도록 쓰여야한다. 


▶ 일반적으로 변수의 초기화는 디폴트 생성자에서 담당하도록 한다.

 이유로는 1. 따로 setter를 통해 초기화를 시켜줄 번거로움이 사라진다는 것. 2. 프로그래밍을 하다보면 변수의 초기화가 이루어지지 않아 오류가 발생하는 경우가 많은데 이러한 오류를 초기에 예방할 수 있다는 점이 있다.



▶ 새로운 객체의 주소값이 생성되는 키워드는 new 뿐이다.

 new는 새로운 객체 주소값을 생성시키고 특정한 값을 담아둔다.(Test test = new Test()) 그리고 그 주소값을 그대로 같은 타입의 변수에게 전달하면 그 변수도 같은 주소값을 공유하게 되므로 한쪽에서 객체를 수정하면 다른 쪽에서도 반영되게 된다.(Test test2 = new Test())


▶ static initializer

static initializer is executed when the class is loaded (or initialized, to be precise, but you usually don't notice the difference).


It can be thought of as a "class constructor".


Note that there are also instance initializers, which look the same, except that they don't have the static keyword. Those are run in addition to the code in the constructor when a new instance of the object is created.

스태틱 이니셔라이져가 디폴트 생성자보다 먼저 생성된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.java.prac;
 
public class LalaLand{
 
    private int var1;
    private int var2;
 
    public LalaLand() {
        System.out.println("default constructor has been performed");
    }
 
    static {
        System.out.println("static has been performed");
    }
 
}
cs


1
2
3
4
5
6
7
8
9
10
11
package com.java.prac;
 
public class MainClass{
 
    public static void main(String[] args) {
 
        LalaLand k = new LalaLand();
 
    }
 
}
cs


>>>

static has been performed

default constructor has been performed


▶자바는 각 블록{} 이 독립적으로 움직이지만, 자바스크립트는 독립된 블록범위를 갖지 않는다.

JAVA

1
2
3
4
5
int x = 1;
{
  int = 2;
}
system.out.println(x) // outputs 1
cs



JAVASCRIPT

1
2
3
4
5
int x = 1;
{
  int = 2;
}
console.log(x) // outputs 2
cs




▶src파일과 bin파일

source code 파일(.java)과 byte code 파일(.class)이 한 폴더에 함께 있는 것은 바람직하지 못하다.
배포할 때에는 실행파일인 바이트코드 파일, 즉 class파일만 배포하는데 여기에 소스코드 파일인 java 파일이 섞여 있으면 관리하기가 불편하기 때문이다.

따라서 두 종류의 파일을 서로 다른 폴더로 분리시켜야 한다.


구분하는 방법은 쉽다.
class파일은 컴파일이 완료되면 생성된다. 
그 말은 컴파일 할 때 옵션을 줘서 어느폴더에 저장될지 지정해주면 된다는 말씀이다.

폴더를 지정해주기 전에, 그 폴더를 만들어줘야 한다.
있지도 않은 폴더에 무언가를 담을 수는 없으니까.

보통은. 일반적으로는. 대부분은.
소스코드(자바 파일)는 source의 약자로 'src'라는 이름으로, 클래스 파일은 binary의 약자로 'bin'이라는 이름으로 폴더를 지정해준다.



출처:http://wanzargen.tistory.com/21?category=700064




1. 톰캣 서버가 설치된 폴더를 등록하기

먼저 톰캣을 이클립스에서 실행하려고 하면, 톰캣이 내 컴퓨터 어디에 저장되어있는지 이클립스가 알야아 한다.


그래서 제일 먼저 해야 할 일은, 설치된 폴더를 찾아서 등록해주는 것이다.


그럼 해볼가.




Eclipse의 설정에서 Server > Runtime Environments 에 들어가보자. 

그러면 아래와 같은 화면이 뜰거시다.

여기서 Add 버튼을 눌러보자.




그럼 아래와 같은 창이 또 뜨는데, 저기에서 내 컴퓨터에 있는 톰캣 버전과 일치하는 항목을 선택한 후, Next 버튼을 클릭!





그러면 아래 화면이 되는데, 

Browse 버튼을 눌러서 실제로 내 컴터에 톰캣이 설치되어 있는,

지금 생각하는 바로 그 폴더를 찾아서 등록해준다.





이렇게 다 하고 Finish버튼을 눌러 완료해주면 끄읏. 짝짝짝-.



여기까지 이클립스에서 톰캣 서버를 실행할 수 있도록, 톰캣이 있는 폴더가 등록 완료된거다.



자. 그러면 이제 다된거 아님??

노노. 등록된거 어떻게 실행시킬거임?

모르겠지?


등록한 서버를 이클립스에서 편하게 실행시킬 수 있는 환경을 만들어보자.



2. 웹 애플리케이션 서버(톰캣) 실행환경 구축하기

 

이클립스에서 Windows > Show View > Servers 를 눌러주면,





요런 창이 뜬다. 이걸 앞으로 "Servers 뷰" 라고 하겠음.




저기에 파란색으로 써있는게 무슨말이냐면

"사용 가능한 서버가 없으니 여기를 눌러서 새로운 서버를 생성해다오"

이 말이다.


저기를 눌러주면,  아래와 같은 창이 뜬다.



어디서 많이 본듯한 이 창은 앞에서 톰캣 폴더를 등록해주는 바로 그 창과 비슷하다.

(앞의 그 창은, 폴더 등록해주는거고요, 이 창은 Servers 뷰에서 간편하게 실행시키기 위해 등록하는 창이다.)


당신의 그 톰캣 버전을 선택하고 Finish를 눌러 완료해주면...


아래처럼 Servers 뷰에 새로운 서버가 보일 것임.




오호라-.


그럼 어디 한번 실행시켜볼가.



3. 웹 애플리케이션 서버 실행환경 시작하기


저기다가 대고 오른쪽 마우스를 클릭하면 아래와 같이 context menu창이 뜬다.


거기서 Start 를 누르면-




이렇게 콘솔 뷰에 뭐라뭐라 뜬다.


톰캣이 정상적으로 시작이 되었나보다 헷.




막 빨간색이라서 첨에 에러난줄 알았ㄷ..






여기서 잠깐.


이클립스에서 톰캣을 실행시키면... 뭐 좀 편하긴 하겠는데,


단지 톰캣을 이클립스에서 편하게 시작/종료시키기 위해 이클립스에서 쓰는걸까?


답은 "노노".


서버가 사용자의 다양한 요청에 대해 동작하려면, 사용자의 요청에 해당하는 웹 애플리케이션이 있어야 한다.

그리고 톰캣은 개발자가 만든 바로 그 애플리케이션들을 실행할 수 있는 환경을 제공하는 서블릿 컨테이너의 역할을 한다.


따라서 웹 애플리케이션 파일을 톰캣 폴더 밑 어딘가에 저장해둔다.

(정확히 어디쯤 저장되는지는 다음 포스트에..)


그런데 문제는.. 수정이 일어나면 그 파일을 수정된 파일로 바꿔줘야 한다. 그래야 수정된 파일이 실행될 것이 아닌가.


뭐 하나 바꿀라 치면 톰캣 폴더 밑에, webapps폴더 밑에, WEB-INF폴더 밑에, classes 폴더 밑에 있는 기존의 파일을 지우고 새로운 파일로 교체....하.

생각만해도 욕지기가 나와.


그런데 이클립스에서 이러케 이러케 해주면, 안그래도 된다 이말씀-.이래서 이클립스 이클립스 하나봐.




정리.


이클립스에서 톰캣 웹 애플리케이션 서버 실행환경을 구축하여 사용하는 이유


=> 수정사항이 있을 때마다 파일을 교체해야 하는 번거로운 작업을 생략할 수 있으니까.












4. 실행환경이 구축된 폴더 확인하기


그러면 이클립스에서는 대체 뭘 어떻게 하길래, 수정된 파일을 바꿔주지 않아도 되는걸까?? 알쏭달쏭 궁금궁금


이클립스 workspace 폴더 > .metadata 폴더 > .plugins 폴더 > org.eclipse.wst.server.core 폴더에 한번 가보자.



<참고>


맥 사용자는  .metadata, .plugins폴더가 안보일 수 있다. 

hidden file이라서 그럼.


Command + Shift + .  이렇게 누르면 나오니까 당황말자.




저기 들어가보면 아래와 같은 파일들이 있을텐데 저기 있는 것들 중에 주목할 것은 "tmp0" 폴더이다.



tmp0 폴더는 이클립스에서 톰캣을 실행하기 전까지는 이 폴더가 안만들어진다.


마냑에 톰캣 실행환경을 여러개 만들어서 실행시키면 tmp0, tmp1, tmp2, ... 이런식으로 생긴다.

(tmp 뒤에 붙는 저 숫자는 폴더가 만들어진 순서대로 붙여지는거니까 신경 안써도 됨.)


저 폴더를 열어보면..


이렇게 많은 것들이 있다. 


이 폴더의 이름이 "tmp~"인데는 다 이유가 있다.


이 폴더는 이름 그대로 '임시폴더'다.


이클립스의 Servers 뷰에서 해당 실행환경을 삭제하면, 이 폴더는 사라진다.


즉, 개발자가 뭘 바꾸면, 똑똑한 이클립스는 지가 만든 임시폴더로 가서 개발자가 바꾼 그 파일을 복붙해놓는다.


그러니까 이 폴더에서 뭔가 열심히 바꿔도 소용이 없다. 서버 삭제하면 이 폴더도 다 날아가니까.



<참고2>


저기서 "wtpwebapps"폴더 밑에 "web01"이라는 폴더가 있는데, 이거슨 다음 포스트에서 소개할 웹 애플리케이션 프로젝트이다.


이클립스에서 웹 애플리케이션 프로젝트를 만들면 무조건 여기에 보이는게 아니고,

"이 프로젝트는 이 톰캣 실행환경에서 실행할거야!" 하고 등록하는 과정을 밟아줘야 함. (이거 다음 포스트에 있음. 겁나친절함.)






서버 구성 파일을 바꾸고 싶다면, 그것도 이클립스에서 바꿀 수 있다.


이클립스 Project Explorer에 가보면 Servers 폴더가 이미 있었거나 새로 생겼을텐데, 여기서 뭐 바꾸고싶은걸 바꾸면 알아서 저기 tmp 폴더 밑에 자동으로 반영이 된다.






-----------------


이것으로 이클립스에서 톰캣을 실행시키는 방법 & 왜 꼭 그래야 하는 이유가 잘 이해되었기를-.




[Concept]


▶object / collection / property / method의 개념
1.object : 

위 그림과 같이 하나의 오브젝트(객체 : 클래스에 의해 인스턴스화된 것)는 property(속성)과 메서드를 갖는다. property는 property 프로시저에 의해 생성되고, 메서드는 function 프로시저에 의해 생성된다.(개체찾아보기에서 각 클래스를 클릭해보면 어떤 property와 method로 구성되어있는지 알 수 있다)

 엑셀에서 오브젝트는 가장 상위개념인 엑셀 어플리케이션 - 워크북 - 워크시트 - 셀 등으로 내려간다. 이때 중요한 것은 하위의 오브젝트는 상위의 오브젝트가 존재하지 않으면 존재할 수 없다. 가령, 엑셀 워크시트가 존재하지 않는데, 셀이 존재할 수는 없는 것이다.


2.collection : 엑셀의 북이나 시트와 같이 동일한 오브젝트가 복수개 존재하는 경우 그것을 모아서 하나로 처리하는 것이 가능한데, 그러한 집합을 collection이라고 부른다. workbook 오브젝트의 집합은 workbooks collection이며, worksheet 오브젝트의 집합은 worksheets collection이다.


3.property : 프로퍼티(속성)은 오브젝트가 가지고 있는 특성이나 설정등에 붙은 이름이다. 오브젝트의 프로퍼티는 반드시 어떤 값을 리턴하는데, 그 리턴값이 타입이 정해져 있음에 유념하자.(각 클래스와 속성과 메서드의 리턴 타입은 개체 찾아보기에서 확인할 수 있다)


4.method : 메서드는 오브젝트의 행동을 결정하는 것이다. 오브젝트의 메서드는 반드시 어떤 값을 리턴하는데,  그 리턴값이 타입이 정해져 있음에 유념하자.(각 클래스와 속성과 메서드의 리턴 타입은 개체 찾아보기에서 확인할 수 있다)


▶오브젝트와 클래스는 다른 개념이다
 클래스로 인스턴스화 하면 오브젝트가 된다. 즉, 클래스는 수단이며 오브젝트는 그 수단에 의한 아웃풋이다.



▶표준모듈과 클래스 모듈의 차이
 표준모듈은 VBA내에서 마크로프로그램을 기재하기 위해서 사용하는 모듈이며, 클래스 모듈은 클래스를 정의하기 위해 사용하는 모듈이다.


▶sub프로시저의 종류/ sub프로시저의 인수
1.sub단독프로시져는 sub가 単体로 사용되는 프로시져로써 일반적으로 마크로표준모듈에 사용하는 sub def() ~ end sub와 같은 모습이다. 따라서 단독프로시저는 인수를 지닐 수가 없다. 반대로 인수가 들어간 프로시저는 단독으로 사용될 수 없고 다른 프로시저에 의해 call 되어야만 사용될 e="margin-right: 0px; margin-left: 0px; padding: 0px; line-height: 1.5;">Dim newSheet

Dim month, day


Set ExcelApp = CreateObject("Excel.Application")


ExcelApp.Application.Visible = True


Set addedWorkBook = ExcelApp.Application.Workbooks.Open("C:/Users/daseul.kim/Desktop/Book1.xlsx")


Set objSheets = addedWorkBook.Sheets


Set newSheet = objSheets.Add(, objSheets(objSheets.Count))


month = Mid(Now - 1, 6, 2)

day = Mid(Now - 1, 9, 2)


newSheet.Name = month & "." & day

addedWorkBook.Save

End Sub

​시트의 가장 끝에 새로운 시트를 추가하는 위와 같은 코딩에서, Set objSheets = addedWorkBook.Sheets에 주목해보자. new를 사용하지 않았다. 왜냐하면, addedWorkBook객체를 생성할 때 sheets객체가 이미 생성되었기 때문에, 초기화할 필요없이 이미 있는 객체값의 주소를 참조만 시키면되기 때문이다!


 Dim x As New Collection과 Dim x As Collection; Set x = New Collection 차이

 프로그램의 성능차이가 존재할뿐 의미상의 차이는 존재하지 않는다.

Dim x As Collection     'Declare ;타입의 선언부로써 인스턴스를 생성한다.

 '자바로 따지자면 Collection x 의 부분. 변수 x의 타입을 설정한다. 자바와 다른 점은 굳이 타입설정을 해주지 않아도 된다는 점인데, 이와같은 경우 바인딩이 런타임중 진행되므로 프로그램의 성능이 떨어진다.

Set x = NeCollection    'Initiate ; 초기화 단계로 New Collection(); 객체 어사인

'변수 x에 Collection 클래스 내용이 담긴 객체 주소를 참조시킨다. 

 VBA코드 작성과 VBS코드 작성의 차이점

VBA는 엑셀 실행 후 작성하는 코딩이기 때문에, 기본적으로 application, workbooks, sheets, cells등의 객체가 생성되어 있는 상태지만, VBS는 말그대로 0에서 시작하기 때문에 하나하나의 객체를 모두 생성해 주어야 한다.



[Technic]


엑셀함수의 Row,Rows와 VBA의 Rows는 역할이 다르다.

함수의 Row() : 참조 셀의 행 번호를 반환한다.

함수의 Rows() : 참조 영역의 행의 갯수를 반환한다.

vba의 Rows() : ()안의 행을 가르킨다.

개체를 변수로 받을 때는 변수 앞에 Set 사용을 잊지말 것
  set은 변수에 개체를 참조하도록 할당하는  것이다. 
스택에 저장되는 기본형 변수는 = 으로 값을 할당하고( A = 23), 힙에 저장되는 객체의 참조형 변수에는 SET으로 주소값을 해서 할당해주어야 한다.(Set A = range("A3"))

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

    Dim area As Range

    Set area = Intersect(Target, Range("N1:N4"))

    If area Is Nothing Then

        Exit Sub

    Else

        MsgBox "수정권한없음"

    End If

    

End Sub

프로시저 창에서 F8을 잘 이용할 것
 프로시저 창 내에서 F8키는 코딩을 한줄 한줄 실행시켜, 디버그가 발생했을 시 원인을 파악하기 쉽게 해준다.


중단점 설정/해제

중단점(Break Point)이란 프로시저가 실행되는 도중에 자동으로 실행을 중지하도록 사용자가 지정해 놓은 위치를 말합니다. 개념적으로는 Stop 문과 비슷한데 마우스 클릭만으로 설정할 수 있다는 것과 워크북을 저장한 다음 다시 열 경우, 중단점은 저장되지 않는다는 점에서 차이가 있습니다. 중단점을 설정하는 방법은 네 가지 정도가 있습니다. 중단점을 설정하려는 행을 선택한 다음,

  • 코드 왼쪽에 있는 여백 표시줄(gray margin)을 클릭한다.

  • <F9> 키를 누른다.

  • '디버그-중단점 설정/해제' 메뉴를 선택한다.

  • 마우스 오른쪽 버튼을 클릭하고 '설정/해제-중단점' 메뉴를 선택한다(이것은 토글 키로, 중단점이 이미 설정되어 있다면 해제합니다).

어느 방법이든 중단점을 설정하면 위의 그림과 같이 여백 표시줄에 커다란 동그라미가 생깁니다. 중단점은 여러 곳에 설정할 수 있으며 설정을 해제하려면 중단점을 클릭하면 됩니다. 설정된 중단점들을 한꺼번에 모두 제거하려면 <Ctrl+Shift+F9> 키를 사용합니다.


'지역' 창 활용

앞에서 '한 단계씩 코드 실행'할 때 <F8> 키를 사용한다고 설명드렸지요? '보기-지역 창' 메뉴를 선택하면 '지역' 창이 표시됩니다. 이 상태에서 <F8> 키를 계속 눌러보면 각 변수에 값들이 어떻게 변하는지 알 수 있습니다.

예전에 순환문이 잘 이해되지 않으면 종이를 한 장 꺼내놓고 몇 번 로직을 돌려보라고 조언해 드렸었지요? '지역' 창을 사용하면 프로시저 내의 모든 변수값이 자동으로 나타나므로 그런 고생을 하지 않아도 됩니다.


Debug.Print 를 이용하여 부분적인 output확인하기

​debug.Print 는 자바의 system.out.println과 동일한 기능이다. debug.print의 결과값은 콘솔창에 표시된다.


메크로 락으로 메크로 보호하기

도구  →  VBAproject속성  →  보호


VBA의 사용자 함수의 return 값

VBA에서 사용자 함수의 return값은 따로 return을 써주는 형식이 아니라, 메서드의 이름을 다시한번 언급하는 형식으로 return값을 선언한다.단! 리턴값이 오브젝트일 경우에는 Set을 붙일 것


Function split_h(text As String, parameter As String, num As Integer)

    Dim arr As Variant

    arr = Split(text, parameter)

    split_h = arr(num - 1)    //사용자 함수의 리턴값 
    'Set 
split_h = arr(num - 1)    //리턴 값이 오브젝트인 경우에는 Set을 쓰고 리턴값을 받는다.

    

End Function

▶엑셀의 셀 내에 vba를 사용하는 방법
vba에서 application.[엑셀내장함수] 를 이용하면 엑셀의 내장함수를 사용할 수 있다고 배웠다. 하지만 sum과 같은 함수의 경우는 어떨까? sheet2의 1행1열 부터 5행 1열까지의 값을 더하고 싶은 경우는 다음과 같이 코딩하면 가능할까?

SUM(sheet2.cells(1,1),sheet2.cells(5,1))
불가능하다. 왜냐하면, 셀에 vba식을 사용하는 것은 불가능하기 때문이다. 따라서 다음과 같은 코딩이 필요하게 된다.

Worksheets("Sheet1").Cells(1, 1).Formula = "=SUM(Sheet2!" & Cells(1, 1).Address & ":" &Cells(5, 1).Address & ")"

▶문자열 내에 따옴표를 넣고 싶을 경우에는 아스키 코드를 사용
abc"d"e 라는 문자열을 출력하기 위해서는 어떻게 해야할까? str = "abc"d"e 를 입력하면 오류가 발생한다. 따라서 이와같은 경우는 아스키 코드를 사용한다 
Chr(34)는 큰따옴표, Chr(39)는 작은따옴표이다.

Dim str As String

str = "abc" & Chr(34) & "d" & chr(34) & "e"

MsgBox str


>>>abc"d"e


▶개발창 F2키를 이용하여 VBA객체 둘러보기(보기 → 개체찾아보기)
 개발창 F1키를 이용하여 함수 둘러보기
 
▶★VBScript는 타입선언을 하면 컴파일이 되지 않는다!
▶★VBScript는 이름으로 인수 설정을 하면 컴파일이 되지 않는다!
autofield field:=1 criteria1="<>"
autofield 1,"<>",,,True


▶VBScript에서 pastespecial의 인수를 사용할 시 값을 사용해야한다.

Sheets("Sheet1").Range("D1").PasteSpecial(-4122)
Sheets("Sheet1").Range("D1").PasteSpecial(-4163)  

▶VBA에서는 도중에 태스크를 멈추기 위해서 Exit sub
 VBS에서는 WScript.Quit


▶nest for or next while을 강제중지하는 방법

Dim done = False

For Each item In itemList
    For Each item1 In itemList1
        If item1.Text = "bla bla bla" Then
            done = True
            Exit For
        End If
    Next
    If done Then Exit For
Next
For Each item In itemList
    For Each item1 In itemList1
        If item1.Text = "bla bla bla" Then
            Goto end_of_for
        End If
    Next
Next

end_of_for:

▶VBS로 엑셀 가동 후 올바른 종료 방법

'1.
Call workbook.Save
Call workbook.Close

Call ExcelApp.Quit

Set ExcelApp = nothing


'2.

Call workbook.Close(True)

Call ExcelApp.Quit

Set ExcelApp = nothing 


▶System.Collections.ArrayList

▶Scripting.FileSystemObject

property

▶読み取り専用으로 읽고 싶지 않을 때
Workbooks.Open은 정말 다양한 파라미터를 갖는데, 읽기 전용으로 읽기 위한 인수가 3번째이고 읽기전용으로 읽지 않기위한 인수가 7번째이다. 

Set workbook =  excelApp.workbook1.Open(dic,,,,,,1)

https://msdn.microsoft.com/en-us/vba/excel-vba/articles/workbooks-open-method-excel


▶utf8로 텍스트를 읽고 싶을 때 : ADODB.Stream Object

Dim objStream, strData Set objStream = CreateObject("ADODB.Stream") objStream.CharSet = "utf-8" objStream.Open objStream.LoadFromFile("C:\Users\admin\Desktop\ArtistCG\folder.txt") Do until objStream.EOS strData = objStream.ReadText(-2) 'ReadText함수는 -1일경우 전체를, -2일경우 한줄을 반환 Wscript.Echo(strData) Loop objStream.Close Set objStream = Nothing

 


▶한 sub에서 다른 sub 불러오기 : 변수를 Global로 선언
Dim global_var As Integer
'

Sub doA()
global_var = global_var + 1
Debug.Print global_var

End Sub

Sub doB()
global_var = global_var + 10
Debug.Print global_var
End Sub

Sub main()
doA
doB
doA
End Sub

▶한 sub에서 다른 sub 불러오기 : call
sub Main()
    Nc As integer
    Dim kij(1 To Nc, 1 To Nc), xi(1 to Nc), a1 As Double
    'I assign values to my variables from the excelsheet e.g. Nc=Cells(1,1) etc.

    Call CalculateA(Nc,kij, xi, a1, a)
    Cells(5,5)=a
end sub

sub CalculateA(Nc as integer,kij as matrix double, xi as array double, a as Double)
    a=0
    For i=1 To Nc
       For j=1 To Nc
          a = a + kij(i,j)*x(i)*x(j)
       Next j
    Next i
    a = a*a1
end sub

▶"대용량 파일이 클립보드에 있습니다" 경고창 닫는 방법
:Excel.Application.CutCopyMode = False

▶외부에서 copy한 내용을 키보드조작으로 엑셀 안에 paste 하기 : SendKeys

Dim excelApp, objBook, objSheet
Dim wshShell
 
'Set Objects
Set excelApp = CreateObject("Excel.Application")
Set wshShell = CreateObject("WScript.Shell")
 
'키보드 조작이기 때문에 UI가 보여야함.
excelApp.Visible = True
 
Set objBook = excelApp.WorkBooks.Open("filePath.xlsx",,,,,,1)
Set objSheet = objBook.Sheets("sheetName")
objSheet.Range("A4").Select
 
'실행하고 있는 어떤 어플리케이션에 키보드 조작을 적용해야하는지 모르기 때문에
'캡션 이름으로 활성화할 대상을 지정
wshShell.AppActivate(excelApp.Caption)
 
'키보드 조작에 대한 더 많은 정보는 msdn정보 참고
Wscript.Sleep(500)
wshShell.SendKeys("^v")
Wscript.Sleep(500)
 
Set wshShell = Nothing
objBook.Close(True)
Call excelApp.Quit
Set excelApp = Nothing


※wshShell.AppActivate(title)
object
WshShell オブジェクトです。
title
アクティブにするアプリケーションを指定します。この引数には、アプリケーションのタイトル バーに表示されるタイトル文字列か、アプリケーションのプロセス ID を指定できます。

解説

AppActivate メソッドは、プロシージャ コールが正常終了したかどうかを示すブール値を返します。このメソッドを呼び出すと、指定されたアプリケーションまたはウィンドウにフォーカスが移りますが、最大化と最小化には影響がありません。ユーザーがフォーカスを切り替えたりウィンドウを閉じたりすると、アクティブなアプリケーション ウィンドウからフォーカスが移ります。

実行中の各アプリケーションのタイトル文字列を title と比較することで、どのアプリケーションがアクティブになるかが決まります。完全に一致するタイトルが見つからない場合、タイトル文字列の先頭が title と一致するアプリケーションがアクティブになります。そのようなアプリケーションが見つからない場合、タイトル文字列の最後が title と一致するアプリケーションがアクティブになります。名前が title と一致するアプリケーションのインスタンスがいくつかある場合、アクティブになるインスタンスは不定です。


sheet.range.autofilter param1,param2,param3,param4,param5

objSheet.Range(param2).AutoFilter param3,Array("派遣"),7,,True

1. Field 첫번째 파라미터 : autofilter의 대상이 되는 range의 행중 몇번째 열을 autofilter할 것인지를 선택한다.
2. Criteria1두번째 파라미터 : 첫번째 필터 대상이 되는 값을 선정한다.만약 multi value를 선택할 시에는
array("first", "second", "third", ..)로 적어준다.
3. Operator세번째 파라미터 :첫번째 파라미터로 array를 지정할 시에는, operator값을 xlFilterValues
7 -> Filter values으로 지정해야한다. 더 다양한 파라미터는 https://msdn.microsoft.com/en-us/vba/excelvba/articles/xlautofilteroperator-enumeration-excel에서 참고
4. Criteria2네번째 파라미터
5. VisibleDropDown다섯번째 파라미터 : 필터 드롭 표시를 할것이냐 안할 것이냐라는 것
6. autofilter는 sub이므로 괄호로 파라미터를 전달할시 can not pass value in parenthese라는 오류가 뜬다.


▶GetBaseName을 사용하면, 확장자를 제외한 파일의 순수한 이름만 뽑아낸다.

▶VBS에서 copyfile 메서드를 사용할 때 주의할 점
1. 괄호를 사용하지 않는다.
2. 파일 패스의 마지막을 \로 닫는다.
1
2
3
If (fso.FileExists(excelPath))=false Then
   fso.CopyFile excelPath, param1&"\" '파일 패스 마지막에 \찍는 것에 매우 주의할 것              
End If
cs


▶byRef와 byVal의 차이


좀더 쉽게 비유하기 위해 c:/program and file/dev/program.exe 라는 1기가짜리 실행파일이 있다고 해보자.

참조 : 75kb짜리 바로가기 아이콘을 만들어서, program.exe의 주소값을 전달하고, 클릭할 때마다 주소값을 통해 c:/program and file/dev/program.exe로 이동 후 프로그램을 실행. 실행하면 기존의  c:/program and file/dev/program.exe에도 영향을 미침)

복제 : 1기가짜리 program.exe을 통째로 복사해서 사용함. 실행해도 기존의  c:/program and file/dev/program.exe에는 영향을 미치지 않고 별도로 움직임





VBSでInclude
VBSには外部ファイルをインクルード・インポートする仕組みがないのですが、ExecuteGlobalを使えばそれっぽいことができます。
Include "Library.vbs"  ' 外部ファイル「Library.vbs」を取込み

Sub Include(ByVal strFile)
  Dim objFSO , objStream , strDir

  Set objFSO = WScript.CreateObject("Scripting.FileSystemObject") 
  strDir = objFSO.GetFile(WScript.ScriptFullName).ParentFolder 

  Set objStream = objFSO.OpenTextFile(strDir & "\" & strFile, 1)

  ExecuteGlobal objStream.ReadAll() 
  objStream.Close 

  Set objStream = Nothing 
  Set objFSO = Nothing
End Sub

ExecuteGlobalに渡した文字列をスクリプトとして解釈して実行してくれる模様。


▶option Explicit / option strict
Option Explicit means that all variables must be declared. See here. Without this, you can accidentally declare a new variable just by misspelling another variable name. This is one of those things that cause a lot of grief as you're trying to debug VB programs and figure out why your program isn't working properly. In my opinion, this shouldn't even be an option - it should always be on.

Option Strict "restricts implicit data type conversions to only widening conversions". See here. With this option enabled, you can't accidentally convert one data type to another that is less precise (e.g. from an Integer to a Byte). Again, an option that should be turned on by default.

▶Activate에 대해 알아보기(selection과의 차이를 통해서)
1.selection과 activate의 
차이는 유연성이다.

Activate make the specified sheet the active sheet, and may only be applied to a single sheet

Select allow for optionally extending the currently selected sheets to include the specified sheet, eg

Worksheets("Sheet2").Select Replace:=False

and also allow for selecting an array of sheets

Sheets(Array("Sheet3", "Sheet2")).Select

2. 메소드를 사용하는 것은 시트탭에 클릭을 하는 것과 같다.
 activate는 쉽게 표현하자면, 외부적인 클릭이라고 생각하면 쉽다. select가 activate 보다 유연할 수 있는 이유는, select는 내부의 리소스로 돌아가지만 activate는 우리가 어떤 객체를 스크린으로 직접 클릭했을 때와 같은 기능을 가지기 때문이다. 스크린으로는 활성화된 하나의 윈도우만 볼 수 있는 것과 같은 의미이다.

3. activate는 스크린, 키보드 조작에 필수적이다.
 위에서 언급했던 바와 같이, activate는 객체를 클릭하여 스크린의 윈도우를 active하는 것이다. 따라서, 스크린에서 가장 외부에 있는 객체를 조작하는 스크린, 키보드 조작에는 일단 activate로 조작 대상인 객체를 가장 외부로 active시키는 과정이 필요하다.

▶이미 열려있는 excel,workbooks,worksheets 의 객체 얻고, 조작하기
1. 현재 열려있는 excel객체로부터 active되어 있는 workbook가져오기
1
2
3
4
5
6
7
8
Dim excelApp
Dim wb
Dim ws
 
set excelApp = GetObject(,"Excel.Application")
Set wb = excelApp.activeWorkbook
Set ws = wb.Sheets(1)
ws.Range("A1").Value = "hahahahahaa"
cs


2. 현재 열려있는 excel객체로부터 특정 이름의 workbook 가져오기

 현재 2개의 workbook이 열려있다. 하나의 workbook이름은 book1.xlsx이며, 다른 workbook이름은 boo2.xlsx일 경우를 가정한다.

1
2
3
4
5
6
7
8
Dim excelApp
Dim wb
Dim ws
 
set excelApp = GetObject(,"Excel.Application")
set wbs = excelApp.Workbooks.Item("book1.xlsx")
set ws = wbs.Sheets(1)
ws.Range("A1").value = "hahahaha"
cs

3. 현재 열려있는 excel객체로부터 내가 원하는 name을 가진 workbook을 가져오기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Dim ExcelApp
Dim objWorkbook, objSheets
Dim args, param
Dim result
 
Set ExcelApp = GetObject(,"Excel.Application")
For Each objWorkbook in ExcelApp.Workbooks
    Wscript.Echo(objWorkBook.Name)
    If objWorkbook.Name = "book3.xlsx" Then
        Exit For ' This is the workbook we wanted
    End If
Next
If objWorkbook.Name = "book3.xlsx" Then
    'objWorkbook is set to book3, so do whatever you like
Else
    ' No book3 found, throw up a message box to warn the user
    MsgBox "No Book3.xlsx file found"
End If
cs


▶숫자로 여러개의 column 지정하기: Range(Column(n),Column(m))
 알파벳으로 column을 설정한다면, ActiveSheet.Column("A:K")의 형식으로 쓸 수 있다. 하지만 숫자를 column과 접목시키려면 어떻게 해야할까? 이럴 때는 Range(Column(1),Column(11))과 같은 형식으로 써주면 된다.

▶셀의 그룹화(range.Group)와 그룹화 숨기기(Sheet.Outline.ShowLevels)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Sub UnitGroupShowTest()
    '//모든 셀의 아웃라인 삭제. 특정 셀의 아웃라인 삭제도 가능함.
    ActiveSheet.Rows.ClearOutline
    
    '//특정 행을 그룹화
    Range("A2:A8").Rows.Group
    Range("A15:A19").Rows.Group
    
    '//특정 행의 그룹화를 감추기
    ActiveSheet.Outline.ShowLevels rowlevels:=1
    
    '//특정 행의 그룹화
    Range("A11:A13").Rows.Group
End Sub
 
cs


▶function(함수)를 부르는 방법
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Function findLastCell(arg1 As String, arg2 As String, arg3 As DateAs range
 
    Dim ws As Worksheet
    Dim startCell As range
    Dim tgCell As range
    Dim i As Integer
    
    Set ws = Sheets(arg1)
    Set startCell = ws.range(arg2)
    
    Debug.Print startCell.Value
    
    i = 1
    Do While startCell(i, 1).Value <> arg3
        i = i + 1
    Loop
 
    Set tgCell = startCell(i, 1)
    
    Set findLastCell = tgCell
    
End Function
 
cs

1. call 을 사용 할 경우에는 ()안에 인수를 줄 수 있다.
1
2
3
4
5
6
7
8
9
10
11
Option Explicit
 
Sub MoveTodoFromDashToTodoList()
 
    Dim tgday As Date
    tgday = Date
    
    Call findLastCell("Dashboard""A1", tgday)
 
End Sub
 
cs


2. call을 사용하지 않는 경우에는 () 없이 인수를 전달해야한다.
1
2
3
4
5
6
7
8
9
10
11
Option Explicit
 
Sub MoveTodoFromDashToTodoList()
 
    Dim tgday As Date
    Dim tgCell As Range
    tgday = Date
    
    CfindLastCell "Dashboard""A1", tgday
 
End Sub
 
cs)

*function의 리턴값을 변수로 할당할 때는 다음과같이 사용한다. 존나 어이없네 시발
1
2
3
4
5
6
7
8
9
10
11
Option Explicit
 
Sub MoveTodoFromDashToTodoList()
 
    Dim tgday As Date
    Dim tgCell As Range
    tgday = Date
    
    Set tgCell = CfindLastCell("Dashboard""A1", tgday)
 
End Sub
 
cs)



-
-
-
-


[Setup Environment Config]


Simultaneous Task running via another user on one bot is not impossible.


環境設定:1.Dic設定 2.Error Handling規約 3.Folder名前作り


▶AA의 유저는 하나의 어카운트에 귀속되므로, 한 어카운트에 이미 귀속된 유저는 다른 어카운트에서 사용할 수 없다.


▶10.5이상의 버전에서만 net4.7이상을 지원한다.


설치시는 sql10.2로 환경설정할 것(10.3으로 하지말것)

한번으로 안될시 -> 기존 설치된 sql2014를 모두 제거 -> 재설치(AACR인스턴스가 존재)




[Dev Environment Config]

▶가장 처음과 끝에 에러 핸들링으로 처리하기


▶devEnDic과 realEnDic을 만들어 개발환경과 본환경의 디렉토리를 구분하기(중복언급)



[AA technic]

Debugging
Debugging button is upper part of page or click the starting part of line makes break point.

 

Put into Log command one task by task

▶파일이나 폴더를 만들때는 if문으로 감싸서, 혹시나 이미 존재하더라도 오류가 나지 않도록 처리할 것


▶되로록이면 키보드가 아닌 오브젝트 조작으로 진행하고, 가장 적합하도록 여러번 테스팅을 거쳐 오류가 나지 않는 조합을 선택하도록


▶runscript 시 파라미터에 공백이 있으면 공백 구분으로 잘라버리므로 오류가 난다.


▶aa에서 DB를 최초로 CSV로 격납시 , 델리미터지만, Excel.Application 객체로 한번이라도 오픈하면 탭 델리미터로 바뀌어버린다.

-> Excel.Application 객체로 오픈한 CSV는 삭제해버릴 것


▶일본어로 된상태에서 키보드 조작하면 폰트가 망가짐


- (Extremely important) Don’t forget to disconnect Database before end, otherwise DB denies AA accessing into DB with error message : commonly trigger insufficient previlege.


As KeyStroke works are sometimes faster than window’s working, put in Delay command after Keystrokes command. 


▶Array를 잘 사용하면 편리


▶내용을 확인 하는 로직을 만들때는 if result="error"를 배치해서 스크립트에서 오류난 거 거르고 그 다음, if result <> "pass" 로 result가 fail일뿐만 아니라 계산 오류로 공백으로 아웃풋되는 것도 거르기


▶이후 운용에 유리할 수 있도록 프로그래밍이 되어 있는가?

-가령 개발패스와 실환경패스를 정하는 부분 등이 운용보수에 편하게 짜여져 있는가?

-스크립트가 하나의 태스크에만 사용되는 것이아니라, 파라미터만 바꾸면 다른 테스크에도 통용될 수 있도록 일반성있게 짜여져 있는가? 스크립트 내의 변수의 위치에는 고정치를 줄 것이 아니라 파라미터를 통한 변수를 줄 것


▶VBScript는 에러핸들링을 해도 AA에서 에러경고창을 띄우지만, JScript는 에러핸들링시 에러경고창을 띄우지않는다.
-The message box which task shows is not shown by AAPlayer hence it cannot be controlled using the Error Handling command in the Task Editor. It is shown by AA_MyVB.vbs. To hide this message box, open AA_MyVB.vbs located at AAE Client installation path and comment following line.
WScript.Echo("Error In Script - " & VbCrlf & err.number & " " & err.description)


▶task와 에러 핸들링은 if 문으로 개별적 에러 처리가 필요. 

10.5버전(최신버전 임에도 불구하고) 아직 task와 script에 대한 에러 핸들링 커맨드가 구비되지 않음.


▶SAP 조작은
첨부파일에 있는 두 단계의 설정을 거쳐 옵션에서 scripting record and play를 실행시키면, 엑셀의 마크로처럼 내가 건들였던 움직임이 VBS로 반환된다.


▶웹 오브젝트 조작에서 오브젝트로 추출된 각 태그의 value를 변수로 선정할 수 있다.


▶스크립트 내에서는 절대 절대디렉토리를 만들지 말고, AA에서 만들어진 변수에 담긴 디렉토리만을 사용해서, 메인테넌스를 일괄화 시켜야한다.


▶웹 메니징 컨트롤에서, 버튼 태그로 되어 있어서 오브젝트 셀렉팅이 되지 않는 경우, 마우스 오른쪽 버튼을 누르면 셀렉팅된다.


▶Run Script에서 파라미터를 넣을 때, 하나의 파라미터를 반드시 ""로 감싸도록한다.

 AA는 띄워쓰기를 하나의 파라미터 단위로 인식하기 때문에, 파일명 자체에 스페이스가 들어가 있으면 하나의 패스를 두개로 나눠서 읽는 참사가 발생한다.


▶기본 변수 설정

변수의 설정 조건 : 1. 고정적으로 사용되어 재사용성이 높은가? 2. 운용에 유리하게 사용될 수 있는 변수인가? 3. 다른 변수에 또 값을 담아 돌려사용할 수 없는가? 꼭 만들어야하는가?

dpRoot : AA는 상대패스가 안되므로 루트 디렉토리를 담는 변수를 만들어 놓고, 이후에 각 path에 dpRoot를 이용하여 디렉토리를 지정한다.
dpRootD

dpRootR


dpInput : 실제 사용하는 디렉토리 변수

pathInputDev : 개발용 디렉토리 변수

pathInputReal: 본환경 디렉도리 변수


dpOutput : 실제 사용하는 디렉토리 변수

pathOutputDev : 개발용 디렉토리 변수

pathOutputReal: 본환경 디렉도리 변수


fpLog : 로그의 위치와 파일명은 고정되있으므로 로그위치 로그파일명을 변수에 담을 것

fpCsv: CSV의 위치는 고정
dpScript :  Script의 위치는 고정


result : 각 태스크의 부분적, 잠정적 결과를 일시적으로 받아냄

resultScript

resultTask


dayOfToday : 오늘의 일

monthOfToday : 오늘의 달

yearOfToday : 오늘의 년


loopingVar : 루프시에는 하나의 변수를 여러곳에서 돌려사용하는 것이 복잡하므로 새로운 루프용 변수를 취득할 것

sqlQuery : sql문을 담음

errorScript : 

errorTask : 

emailReceiver : 


-변수 외에는 절대 하드코딩 하지 않는다. 예를 들어 파일패스와 같은 경우는 변수에 값을 넣고 변수를 전달하지, 파일패스에 직접 하드코딩하는 일은 없도록한다. 나중에 메인테넌스 시 어디를 하드 코딩 했는지 판단이 불가능하고 이는 프로그램 오류를 발생하기 때문이다. 언제 누구에 의해서라도 통제될 수 있도록 변수만 활용하도록 한다.



[Maintainance]

▶스케쥴러를 실행한 어카운트가 로그 아웃 시 스케쥴러의 시행도 불가능하다.


▶스케쥴러보다 트리거가 우선된다.


▶스케쥴러가 여러개 동일한 시간에 시행될시 priority에 따라 실행 순서가 바뀐다.


▶ development 권한을 가진 clinet 유저는 세부적 스케쥴링이 불가능하고, one time only 스케쥴링만 가능하게된다.


▶ os가 영어가 아닐시 monthly 스케쥴러가 실행되지 않는다.


▶ 컨트롤룸은 20분이 지나면 자동으로 유저가 로갓된다.

+ Recent posts