반응형


        /* 
        * 
        * 같은 값이 있는 열을 병합함
        * 
        * 사용법 : $('#테이블 ID').rowspan(0);
        * 
        */
        $.fn.rowspan = function(colIdx, isStats) {
            return this.each(function() {
                var that;
                $('tr', this).each(function(row) {
                    $('td:eq(' + colIdx + ')', this).filter(':visible').each(function(col) {

                        if ($(this).html() == $(that).html()
        && (!isStats
        || isStats && $(this).prev().html() == $(that).prev().html()
        )
        ) {
                            rowspan = $(that).attr("rowspan") || 1;
                            rowspan = Number(rowspan) + 1;

                            $(that).attr("rowspan", rowspan);

                            // do your action for the colspan cell here            
                            $(this).hide();

                            //$(this).remove(); 
                            // do your action for the old cell here

                        } else {
                            that = this;
                        }

                        // set the that if not already set
                        that = (that == null) ? this : that;
                    });
                });
            });
        };


        /* 
        * 
        * 같은 값이 있는 행을 병합함
        * 
        * 사용법 : $('#테이블 ID').colspan (0);
        * 
        */


        $.fn.colspan = function(rowIdx) {
            return this.each(function() {

                var that;
                $('tr', this).filter(":eq(" + rowIdx + ")").each(function(row) {
                    $(this).find('td').filter(':visible').each(function(col) {
                        if ($(this).html() == $(that).html()) {
                            colspan = $(that).attr("colSpan");
                            if (colspan == undefined) {
                                $(that).attr("colSpan", 1);
                                colspan = $(that).attr("colSpan");
                            }
                            colspan = Number(colspan) + 1;
                            $(that).attr("colSpan", colspan);
                            $(this).hide(); // .remove();  
                        } else {
                            that = this;
                        }

                        that = (that == null) ? this : that; // set the that if not already set  
                    });
                });

            });
        }

        $('#head').rowspan(0);
        $('#head').colspan(0);

반응형
Posted by Hippalus
,

반응형

DECLARE @i int, @sql varchar(1000)

DECLARE @tablename varchar(1000),@ownerName  varchar(1000)

 

SET @i = 1

 

DECLARE DB_Cursor CURSOR FOR 

 SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES  WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_SCHEMA, TABLE_NAME

OPEN DB_Cursor

 

FETCH NEXT FROM DB_Cursor

INTO @ownerName, @tablename

WHILE @@FETCH_STATUS = 0

BEGIN

 

 SET @sql = 'ALTER INDEX ALL ON ' + @ownerName + '.' + @tablename + ' REBUILD WITH (PAD_INDEX = ON, FILLFACTOR = 90) '

 EXEC (@sql)

 

 PRINT CONVERT(VARCHAR, @i) + '__' + @ownerName + '.' + @tablename + '............ OK'

 SET @i = @i + 1

 

 FETCH NEXT FROM DB_Cursor

 INTO @ownerName, @tablename

 

END

 

CLOSE DB_Cursor

DEALLOCATE DB_Cursor

반응형
Posted by Hippalus
,

반응형

기본브라우저 호출 : ShellExecute(NULL, "open", strWebPage, NULL, NULL, SW_SHOWNORMAL);

기본브라우저 무시 I.E 호출 : ShellExecute(NULL, "open", "C:\\progra~1\\intern~1\\iexplore.exe", strWebPage, "", SW_SHOWNORMAL); 

반응형
Posted by Hippalus
,

반응형

개발하다보면 datetime이 NULL인 경우가 종종 있다.
(NULL도 엄연히 자료이고 무서워해선 안된다.)

SELECT expiredate AS expiredate FROM MEMBER_TBL
실행시 expiredate가 null이라면 출력 결과를 사용할 때 안전하게 또는 예쁜 결과를 얻기 위해 isnull(expiredate, '')과 convert함수를 동원하여 쿼리를 돌려보면 예상과 다르게 1900-01-01 이 짜잔하고 나타난다.

이땐 COALESCE 함수를 사용하면 원하는 결과인 공백을 얻어낼 수 있다.
SELECT COALESCE(CONVERT(CHAR(10), expiredate), '') AS expiredate FROM MEMBER_TBL

stackoverflow.com에도 잘 설명되어 있다.
https://stackoverflow.com/questions/26282007/convert-null-datetime-to-blank/52191530

반응형
Posted by Hippalus
,

MSSQL OUTER APPLY

모바일 & 앱 2021. 7. 23. 10:06

반응형

SELECT
*
FROM
TABLE1 AS TBL1
OUTER APPLY (
  SELECT
     *
  FROM
     JOINTABLE AS TBL2
  WHERE
      TBL1.KEY = TBL2.KEY ) AS RESULT

 

자꾸 까먹어서 써놓음

반응형
Posted by Hippalus
,

반응형

    Function ARRAYMERGE( arr1, arr2 )

        dim arr1_size, arr2_size, total_size, i, counter

        

        if not isArray( arr1 ) then 

            arr1 = Array( arr1 )

        end if

        

        if not isArray( arr2 ) then 

            arr2 = Array( arr2 )

        end if

        

        arr1_size = ubound( arr1 ) : arr2_size = ubound( arr2 )

        total_size = arr1_size + arr2_size + 1

        counter = arr1_size + 1

        

        Redim Preserve arr1( total_size )

        For i = lbound( arr2 ) to arr2_size

            If isobject( arr2( i ) )then

                set arr1( counter ) = arr2( i )

            Else

                arr1( counter ) = arr2( i )

            End if

            counter = counter + 1

        Next

        ARRAYMERGE = arr1

    End Function

반응형
Posted by Hippalus
,

반응형

DIV태그 안에 컨텐츠를 넣고 프린트시 자칫 짤림 현상이 나타날 수 있음
이때 style로 media print에 클래스로 아래와 같이 지정해주고 div에 해당 클래스명을 지정해주면 프린트 할 때 알아서 다음 페이지로 잘 넘어가진다.

<style type="text/css">
        @media print {
            .page-break { page-break-inside:avoid; page-break-after:auto }
        }
</style>

<div class="page-break">
    <div><br>TEST</div>
</div>
<div class="page-break">
    <div><br>TEST</div>
</div>
.
.
.
<div class="page-break">
    <div><br>TEST</div>
</div>

$("#BTNE").click(function(e) {
    e.preventDefault();

   
window.print();
});

 

반응형
Posted by Hippalus
,

반응형

보통 Xcode에서 빌드시 연결 오류가 나면 연결잭을 분리 후 다시 연결하면 대부분 해결 되는데 이번엔 해결 되지 않고 이런 오류를 내뱉는다.

이럴 땐 아이폰을 재시작하면

해결된다.


잘 동작한다.

항상 느끼지만 윈도우 개발보다 모바일 앱 개발은 디바이스부터 개발 언어의 잦은 변경질까지 다양한 요소들까지 신경써줘야 한다.

반응형
Posted by Hippalus
,

반응형

iOS 앱을 만들다 보면 가장 처음 접하게 되는 문제가 이 키보드 가림 문제이다.
보통 책이나 웹상에 떠도는 소스들을 보다보면 매우 간단하게 UITextFiled 하나만 배치하여 키보드가 나타나면 뷰를 올려주고 키보드가 내려가면 다시 뷰를 내려주는 단순한 상황만 언급할 뿐 실제 현업에서 발생 가능한 UITextField가 여러개일 때
즉 상단에 위치한 UITextField컨트롤은 키보드가 보여줘도 그대로 놔둬야 하고 하단에 위치한 UITextField 컨트롤은 키보드만큼 올려줘야 하는 상황에 대해 제대로 해결책을 제시하는 글은 찾기 힘들다.
오늘 소개할 이 방법 말고도 여러 방법들이 있겠지만 초보자도 쉽게 따라할 수 있는 방법을 택하여 소개하고자 한다.

대략 순서는 이러하다.
1. viewDidLoad에서 UITextField Delegate  연결 
2. viewDidLoad에서 NotificationCenter를 이용하여 Observer 등록 : 키보드 Show, Hide 이벤트 확인
3. UITextField가 키보드에 가려졌는지 확인을 위한 해당 컨트롤의 위치좌표(Y) 확인
4. 가려졌다면 뷰 이동 O, 안가려졌다면 뷰 이동 X
5. 모든 작업 종료 후 viewWillDisappear에서 2번에서 등록했던 Observer 제거

입력 전 화면
첫번째 컨트롤에 포커스 된 화면(키보드가 가려지지 않으므로 뷰 이동 X)
두번째 컨트롤에 포커스 된 화면(키보드가 가려졌으므로 뷰 이동 O)
세번째 컨트롤에 포커스 된 화면(키보드가 내려간 상태였다면 뷰 이동이 되어야 하지만 이미 키보드가 올라온 상태이므로 뷰 이동 X)

1. TextField의 처리를 위해 UITextFieldDelegate 프로토콜 추가
(이후 TextField 컨트롤은 편의상 컨트롤이라 칭함)
class
MyViewController: UIViewController, UITextFieldDelegate {
}

2. 컨트롤 변수와 컨트롤을 연결(너무 기초라 패스)
위에서부터 순서대로 txtTmp, txtId, txtPw
    @IBOutlet weak var txtTmp: UITextField!
    @IBOutlet weak var txtId: UITextField!
    @IBOutlet weak var txtPw: UITextField!

3. viewDidLoad()에서 컨트롤 변수의 delegate 연결 및 키보드를 내리기 위해 완료 버튼(done)을 추가해준다.
        txtTmp.delegate = self
        txtId.delegate = self
        txtPw.delegate = self

        txtTmp.returnKeyType = .done
        txtId.returnKeyType = .done
        txtPw.returnKeyType = .done

4. 키보드가 올라왔나 내려갔나 확인을 위해 NotificationCenter로 Observer 등록        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
이렇게 구현하면 keyboardWillShow, Hide가 없다고 에러가 뜰텐데 원칙상 선 구현 후 정의를 내려야 하지만 편의상 그냥 구현한다.

5. 키보드가 올라왔을 때 컨트롤이 키보드에 가려졌을 때 뷰를 그만큼 올려주는 처리와 내려갔을 때 뷰의 위치를 다시 되돌려 놓는 처리 그리고 지금 컨트롤이 키보드에 가려졌는지 안가려졌는지 확인을 위한 처리 구현

먼저 키보드가 컨트롤을 가렸는지 확인을 위해 변수 하나를 실수형으로 선언한다.
    var
fCurTextfieldBottom: CGFloat = 0.0

현재 포커싱된 컨트롤의 좌표를 구하기 위해 textFieldDidBeginEditing에서 현재 컨트롤의 y좌표와 해당 컨트롤의 높이를 더하면 나중에 키보드에 의해 가려졌는지 확인이 가능하므로 계산 후 일단 보관해둔다.
    func textFieldDidBeginEditing(_ textField: UITextField) {        
        fCurTextfieldBottom = textField.frame.origin.y + textField.frame.height    
    }

이제 4번에서 등록한 selector함수인 키보드가 나타났을 때와 내려갔을 때 함수를 구현한다.
키보드의 사이즈(구조체)를 keyboardSize에 보관 후 현재뷰의 높이에서 빼주면 키보드가 잡아먹는 정확한 위치를 알 수 있다.
이를 앞서 계산해 보관해둔 fCurTextfieldBottom와 비교하여 fCurTextfieldBottom가 작거나 같으면 가려지지 않았으니 무시하고 크다면 1px이라도 가려졌으므로 현재 뷰를 키보드가 잡아먹는 높이만큼 올려주면 된다.
    @objc func keyboardWillShow(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
            if fCurTextfieldBottom <= self.view.frame.height - keyboardSize.height {
                return
            }
            if self.view.frame.origin.y == 0 {
                self.view.frame.origin.y -= keyboardSize.height
            }
        }
    }

키보드가 사라졌을 땐 간단하다.
그냥 뷰가 이동됐으면 다시 원상복구해주고 아니면 아무런 처리를 하지 않는다.
    @objc func keyboardWillHide(notification: NSNotification) {
        if self.view.frame.origin.y != 0 {
            self.view.frame.origin.y = 0
        }
    }

앞서 추가했던 done의 처리도 해주어 키보드가 내려가게끔 구현해준다.
    func textFieldShouldReturn(_ textField: UITextField) -> Bool
         textField.resignFirstResponder()
         return true
     }

이렇게만 해두면 기본적인 처리는 다 되었고 만약 완료버튼(done) 대신 뷰의 아무곳이나 터치했을 때 키보드가 내려가길 원한다면
viewDidLoad에 제스쳐를 등록 후 
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(endEditing)))

관련 함수를 구현해주면 깔끔하게 처리가 가능하겠다.
   
@objc func endEditing() {
        txtTmp.resignFirstResponder()
        txtId.resignFirstResponder()
        txtPw.resignFirstResponder()
    }

 

반응형
Posted by Hippalus
,

반응형

- (void)viewDidLoad {
     [super viewDidLoad];

     
UIView *view = [UIView new];
     view.backgroundColor = [UIColor redColor];

     
[view setTranslatesAutoresizingMaskIntoConstraints:NO];
     [self.view addSubview:view];
     
     NSLayoutConstraint *left = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeLeftrelatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1 constant:100];

     NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:100];

     NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:50];

     NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:50];

     [self.view addConstraints:@[left, top]];
     [view addConstraints:@[height, width]];
}


width에 constant를 뷰의 넓이와 동일하게 한다면
CGRect rcData = [[UIScreen mainScreen] bounds];
     NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:rcData.size.width];


반응형
Posted by Hippalus
,