>source

아래에 매크로를 기록했는데 내 컴퓨터에서 잘 작동합니다 (2016). 그러나 Excel 2013을 사용하여 다른 컴퓨터에서 실행하면 "구문 오류"가 발생하고 수식을 강조 표시하여 V 열 "상태"를 계산합니다. 또한 2 개의 새로운 열을 추가하지 않고 U "날짜"열을 계산하지 않음을 의미하기 전에 모든 것을 건너 뛰는 것 같습니다. 이 문제를 해결하는 방법에 대한 아이디어가 있습니까? 2 Excel 버전 간의 구문 차이를 알지 못합니다. 감사합니다!

Sub ReportingStatus()
    Dim LastRow As Range
    'Add 2 columes and format them
    Range("U6").Select
        ActiveCell.FormulaR1C1 = "Dates"
        Range("V6").Select
        ActiveCell.FormulaR1C1 = "Status"
        Range("T6").Select
        Application.CutCopyMode = False
        Selection.Copy
        Range("U6:V6").Select
        Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
            SkipBlanks:=False, Transpose:=False
        Application.CutCopyMode = False
        Range("S65536").End(xlUp).Select
        ActiveCell.Offset(0, 2).Select
        Set LastRow = ActiveCell
    'Calculate the value for column U "Date"
        Application.ScreenUpdating = False
        Range("U7", LastRow).Select
        Selection.FormulaR1C1 = _
            "=IF(RC[-2]=""Awaiting Management Response"",R2C1-RC[-9],IF(RC[-3]<>"""",MAX(RC[-3]-RC[-4],R2C1-RC[-3]),R2C1-RC[-4]))"
        LastRow.Offset(0, 1).Select
    'Calculate the value for column V "Status"
        Range("V7", ActiveCell).Select
        Selection.FormulaR1C1 = _
            "=IF(RC[-3]=""Awaiting Management Response"",IF(RC[-1]<1,""MGMT-CURRENT"",IF(AND(1<=RC[-1],RC[-1]<=60),""MGMT-DELAYED"",IF(AND(61<=RC[-1],RC[-1]<=90),""MGMT-SIGNIFICANTLY DELAYED"",""MGMT-CRITICAL""))),IF(RC[-1]<1,""CURRENT"",IF(AND(1<=RC[-1],RC[-1]<=60),""DELAYED"",IF(AND(61<=RC[-1],RC[-1]<=90),""SIGNIFICANTLY DELAYED"",""CRITICAL""))))"
        Range("V7").Select
        Columns("U:V").EntireColumn.AutoFit


  • 답변 # 1

    테스트 데이터가 충분하지 않으며 Excel 2013에 액세스 할 수 없으므로 구문 오류를 복제하거나 매크로가 원하는 작업을 수행하는지 확인할 수 없습니다.

    매크로 레코더에서 생성 된 코드를 사용하면 VBA를 처음 접한 것 같습니다. 이 답변에는 여러 섹션이 있습니다. 각 섹션에서 나는 당신이 모르거나 오해하는 것을 설명하려고 시도합니다. 여기에 많은 정보가 있습니다. 천천히 읽고 각 단락을 이해하려고 노력하십시오. 단락을 이해할 수 없으면 계속해서 나중에 다시 오십시오. VBA 프로그래머가 되려면 결국 모든 것을 이해해야한다고 생각합니다. 하지만 오늘 하루 종일 그것을 이해할 필요는 없습니다.

    문제는 V 열의 길고 복잡한 수식이라고 생각합니다. Excel 2003의 경우 수식의 최대 길이는 255 자입니다. 중첩에도 한계가있었습니다. 이후 버전은 훨씬 더 긴 수식과 더 많은 중첩을 허용합니다. VBA 컴파일러의 일부 버전에서는 Excel에서 허용하지 않는 수식을 거부한다는 제안이 있습니다. 필자의 매크로에서는 긴 공식을 더 짧고 이해하기 쉬운 부분으로 나누었습니다.

    오류가 발생한 것 : 편집기, 컴파일러 또는 통역사

    당신은 다음과 같이 불평합니다 :"또한 이전에 모든 것을 건너 뛰는 것 같습니다. 즉, 2 개의 새로운 열을 추가하지 않고 U "날짜"열을 계산하지 않습니다. " 이것으로부터, 나는 당신이 다양한 단계와 언제 점검되는 것을 이해하지 못한다고 추론합니다.

    소스 코드를 입력하면 편집기가 확인합니다. If A=1 작성  에디터는 즉시 If 를 알려줍니다   Then 없이는 유효하지 않습니다 .

    [Debug]를 클릭 한 다음 [CompileVBAProject]를 클릭하면  모든 모듈에서 모든 매크로를 컴파일하고 있습니다. [Run] 또는 [F5]를 클릭하면  컴파일러에서 오류를 발견하지 않으면 현재 매크로에 대해 컴파일러를 실행하여 해석기를 시작합니다.

    컴파일러는 오류를 발견하지 않으면 소스 코드를 즉시 코드로 처리합니다. 즉, 컴파일러는 사람이 읽기 쉬운 것을 인터프리터가 읽기 쉬운 것으로 변환합니다. 컴파일러는 "변수가 정의되지 않음"또는 "변수가 두 번 정의 됨"과 같은 오류를 발견 할 수 있습니다.

    인터프리터는 VBA 매크로를 실행하는 프로그램입니다. Cells(RowCrnt, ColCrnt).Value = 1 와 같은 것을 쓰면 RowCrnt 의 현재 값을 알 수있는 것은 통역사입니다.  는 0이며 해당 행이 없다고보고합니다.

    V 열을 만들려고 할 때 통역사가 오류를 발견 한 경우 매크로의 초기 부분에 순종하고 U 열에 새 열 머리글과 수식이있을 것입니다.

    편집기가 오류를 발견하면 줄을 완성 할 때 메시지가 나타납니다. 메시지를 수락하고 전화를 끊으면 빨간색으로 바뀝니다.

    [Run] 또는 [F5]를 클릭했는데 오류가보고되기 전에 아무 것도 발생하지 않은 것 같습니다. 컴파일러가 오류를 발견했기 때문입니다. [Run] 또는 [F5]와 약간 혼동되어  인터프리터가 시작되기 전에 첫 번째 매크로 만 컴파일되었습니다. 첫 번째 매크로가 두 번째 매크로를 호출하면 두 번째 매크로는 호출 될 때만 컴파일됩니다. 두 번째 매크로에 오류가 있으면보고됩니다. 두 번째 매크로 호출까지 첫 번째 매크로의 명령문은 수행되었지만 두 번째 매크로의 명령문은 수행되지 않았습니다.

    때때로 오류 메시지가 명확하고 오류를 수정하는 방법을 알고 있습니다. 다른 경우에는 오류를보고 한 내용을 식별하는 것이 매우 도움이 될 수 있습니다.

    매크로 레코더

    매크로 레코더는 무엇을하려고하는지 모릅니다. 그것은 당신이 무엇을 달성하려고하는지 이해하지 않고, 당신이하고있는 일, 진술에 의한 진술을 기록합니다. 예를 들면 다음과 같습니다.

    커서를 U6 셀로 옮겼습니다. "날짜"를 입력했습니다 커서를 V6 셀로 옮겼습니다. '상태'를 입력했습니다.

    매크로 레코더는 이것을 다음과 같이 기록했습니다 :

    Range("U6").Select
    ActiveCell.FormulaR1C1 = "Dates"
    Range("V6").Select
    ActiveCell.FormulaR1C1 = "Status"
    
    

    구문 적으로 올바른 VBA이지만 VBA가 좋지 않습니다. 인터프리터가 화면을 다시 페인트해야 선택한 셀이 표시되므로 셀 선택은 느린 명령입니다. Application.ScreenUpdating = False 를 추가하여 셀 선택 속도를 높일 수 있습니다  매크로 상단에 있지만 여전히 느립니다.

    프로그래머는 다음과 같이 쓸 것입니다 :

    Range("U6").Value = "Dates"
    Range("V6").Value = "Status"
    
    

    프로그래머는 커서를 움직일 필요가 없다는 것을 알고 있기 때문에

    실제로, 좋은 프로그래머는 그것을 쓰지 않을 것입니다. 이 코드는 특정 워크 시트에서만 작동합니다. 좋은 프로그래머가 다음과 같이 작성할 수있는 워크 시트의 이름이 "작업"이라고 가정합니다.

    With Worksheets("Tasks")
      .Range("U6").Value = "Dates"
      .Range("V6").Value = "Status"
    End With
    
    

    매크로 레코더는 Worksheets("Data").Activate 를 기록합니다  워크 시트를 전환했지만 기록을 시작할 때 활성화 된 워크 시트를 기록하지 않는 경우

    With 추가  그리고 End With  문 앞에 마침표를 추가하고 추가하면 두 가지 이점이 있습니다. (1) 매크로가 시작될 때 잘못된 워크 시트가 활성화 된 경우에도 여전히 작동합니다. With 없이  매크로는 다른 워크 시트 전체에 쓰여졌으며 실행 취소 명령은 매크로가 수행 한 작업을 취소하지 않습니다. (2) 귀 하나 다른 사람이이 매크로를 6 개월 또는 12 개월 안에 업데이트해야 할 경우이 코드의 대상이되는 워크 시트가 분명합니다.

    다음은 :

    Range("T6").Select
    Application.CutCopyMode = False
    Selection.Copy
    Range("U6:V6").Select
    Selection.PasteSpecial Paste:=xlPasteFormats, Operation:=xlNone, _
      SkipBlanks:=False, Transpose:=False
      Application.CutCopyMode = False
    
    
    이 코드가 달성 한 것을 해결하는 데 시간이 걸렸습니다. 머리글의 이전 셀에서 새 셀로 형식을 복사하고 있습니다. 중요하지 않은 일회성으로도 명령을 느리게합니다. 더 중요한 것은 누군가 12 개월 안에이 매크로를 업데이트해야 할 때이 코드를 해독하는 데 얼마나 많은 시간을 소비합니까?

    같은 효과를 얻는 방법에는 여러 가지가 있습니다. 내가 갈 것 같아요 :

    With Worksheets("Tasks")
       .Range("T6").Copy Destination:=.Range("U6:V6")  ‘ Copy everything but only need formats
      .Range("U6").Value = "Dates"
      .Range("V6").Value = "Status"
    End With
    
    

    새로운 성명에서 Destination:=  선택 사항이지만이 진술이 무엇을하고 있는지 명확하게 생각하기 때문에 항상 포함합니다. 이 의견은 향후 유지 보수 프로그래머가이 진술의 목적을 이해하는 데 도움이 될 것입니다. 의견이 없으면 모든 사람들이 Copy 를 인식하지 못하기 때문에 셀 T6에서 값을 복사하는 것처럼 보일 수 있습니다서식도 복사합니다.

    다음 명령은 :

    Range("S65536").End(xlUp).Select
    
    
    이 진술은 저를 많이 귀찮게합니다. 65,536은 Excel 2003의 마지막 행입니다. 그 이후 마지막 행은 1,048,576입니다. 이것은 매크로 레코더가 기록하는 것이 아닙니다. 이 문장을 입력 했습니까? 그렇다면 왜"S65536"입니까? Excel 2016에서 Excel 2003 통합 문서를 유지하려고하십니까?

    Excel 2016과 Excel 2013을 모두 사용한다고합니다. Excel 2003도 사용하고 있습니까? 여러 버전의 Excel을 사용하는 경우 매우주의해야합니다. Microsoft는 제품을 앞뒤로 호환하기 위해 노력하고 있지만 이는 100 % 호환성을 의미합니다. 최신 버전에는 이전 버전에서 작동하지 않는 기능이 있습니다. Excel 2007은 Excel 2003을 완전히 다시 작성했으며 비 호환성 시점에 보고서가있었습니다. 이러한 비 호환성은 Excel 2010에서 수정되었으므로 Excel 2010은 Excel 2007보다 Excel 2003과 더 호환됩니다. Excel 2016 용으로 작성된 매크로가 이전 버전에서 작동한다고 가정 할 수 없습니다. 아마도 그럴 것이지만 그러한 매크로를 완전히 테스트해야합니다. 가장 큰 원인은 아니지만 버전 간 비 호환성으로 인해 구문 오류가 발생할 수 있습니다.

    마지막 행을 식별 할 때의 전체 블록은 :

    .Range("S65536").End(xlUp).Select
    ActiveCell.Offset(0, 2).Select
    Set LastRow = ActiveCell
    
    

    LastRow  마지막 행이 아니라 U 열의 마지막 셀입니다. 이름이 잘못되어 일부 재난이 발생했습니다. 유지 보수 프로그래머는 변수 이름에 변수의 이름을 올바르게 식별하고이 가정에서 새 코드를 작성한다고 가정합니다.

    다른 버전의 통합 문서를 유지하기 위해 한 Excel 버전에 대한 매크로를 작성하지 않았으므로 다음을 테스트해야합니다.

    활성 워크 시트의 S 열에 최대 행을 표시하려면 다음과 같이 작성하십시오.

    LastRow = Cells(Rows.Count, "S").End(xlUp).Row
    
    

    활성 With 에 명명 된 워크 시트의 S 열에 최대 행을 가져 오려면  진술, 작성 :

    LastRow = .Cells(.Rows.Count, "S").End(xlUp).Row
    
    

    Rows.Count  워크 시트의 행 수를 반환합니다. 열려있는 모든 통합 문서의 모든 워크 시트에 동일한 수의 행이 있었기 때문에 어떤 통합 문서가 중요한 매크로를 작성하지 않았습니다. Excel 2003 이상 통합 문서에 모두 액세스하는 경우 크기가 다른 워크 시트가 있으므로 원하는 수를 세 심하게 확인해야합니다.

    Range("Xn") 대신 나는 Cells(RowNumber, ColumnId) 를 작성했습니다 . 이것은 셀을 식별하는 또 다른 방법입니다. RowNumber는 정수 또는 정수 표현식이어야합니다. ColumnId는 문자 (예 : "S")이거나 ColumnNumber, 정수 (예 : 20) 또는 정수 표현식으로 대체 될 수 있습니다.

    열의 셀에 액세스하는 경우 :

    For ColCrnt = 1 to 20
      "    "    "
    Next
    
    당신은 정말 Cells(RowNumber, ColumnNumber) 가 필요합니다   나는 Range 를 갖지 않기 위해 일관성을 유지하고 싶다  하나의 진술과 Cells 에서  다음에. 나는 항상 Cells 를 사용합니다  단일 셀과 Range(Cells(TopRow, LeftColumn) , Cells(BottomRow, RightColumn)) 를 참조 할 때마다  직사각형. 필수는 아니지만 시간이 지남에 따라 일관성이 유지됩니다.

    Application.ScreenUpdating = False  매크로 상단에 있어야합니다.

    바 꾸었습니다 :

    'Calculate the value for column U "Date"
    Range("U7", LastRow).Select
    Selection.FormulaR1C1 = _
            "=IF(RC[-2]=""Awaiting Management Response"",R2C1-RC[-9],IF(RC[-3]<>"""",MAX(RC[-3]-RC[-4],R2C1-RC[-3]),R2C1-RC[-4]))"
    
    

    기준

    'Set all used cells in column U ("Date") to the required formula
    .Range(.Cells(7, "U"), .Cells(LastRow, "U")).Value = _
             "=IF(RC[-2]=""Awaiting Management Response"",R2C1-RC[-9],IF(RC[-3]<>""""" & _
             ",MAX(RC[-3]-RC[-4],R2C1-RC[-3]),R2C1-RC[-4]))"
    
    

    나는 Range(Cells(TopRow, LeftColumn) , Cells(BottomRow, RightColumn)) 를 사용했다  위에서 언급 한 구문. 화면 오른쪽에서 사라지는 문장이 마음에 들지 않기 때문에 긴 글자를 나누었습니다.

    열 V와 비슷한 작업을 수행했습니다. 열 V에서 작업하는 동안 가능한 문제를 식별했습니다. 셀 V7의 수식 길이는 276 자입니다. 이 길이의 수식은 Excel 2003에서 유효하지 않았지만 찾을 수있는 모든 문서는 이후 버전에서 모두 유효하다고 제안합니다. Excel 2003을 사용하는 경우 컴파일 타임에 발견되는 이유를 이해하지 못하더라도 문제가 될 수 있습니다. 말했듯이, 컴파일 시간 오류가 될 줄의 길이에 대한 제한에 대한 보고서가 있습니다. 문자열을 약식으로 시도 할 수 있습니다. 예를 들어 "MGMT-SIGNIFICANTLY DELAYED"대신 "MSigDel"

    다른 방법은 공식을 나누는 것입니다. 수정해야 할 필요가 있는지 이해하기 쉬운 공식은 아닙니다. 분할하면 이해하고 수정하기가 훨씬 쉬워집니다. 아래의 최종 코드에서 수식을 분할했습니다. 테스트 데이터가 없어서 올바르게 분할한다고 약속 할 수는 없지만 가지고 있다고 생각합니다.

    상수

    코드를 한 줄씩 살펴 보니 매크로 수정을 중단 할 수있었습니다. 매크로 레코더로 생성 된 불량한 VBA를 수정하면 매크로가 개선되었지만 요구 사항이있는 경우에는 작성했던 매크로가 아닙니다.

    나는 6, A2, L, Q, R, U 또는 V를 내 코드에 쓰지 않을 것이다. 현재 열 제목이 6 행에 있지만 변경 될 수 있습니다. 추가 열이 추가되면 열 U와 V가 이동해야합니다. 6과 6에 대한 코드를 살펴보면 Us와 Vs는 고통스럽고 하나를 놓치기 쉽습니다. 두 개의 열이 서로 바뀌어 모든 Es가 F가되고 그 반대의 경우도 더 나쁩니다. 상수를 사용하는 것이 훨씬 낫습니다 :

    Const ColLastExist As String = "T"    ' The last column in the main report
    Const ColFrstNew As String = "U"      ' The first status column
    Const ColLastNew As String = "V"      ' The last status column
    Const RowHead As Long = 6             ' Row containing column headers
    
    

    기존의 기존 열에서 서식을 이동하려고합니다. 이것은 현재 열 T이지만 새 열을 추가하면 변경 될 수 있습니다. 현재 첫 번째 새 열은 U이고 마지막 열은 V입니다. 다른 열이 주 보고서에 추가되면 이동합니다. 여분의 새 열이있을 수도 있습니다.

    형식을 옮기는 문장은 다음에서 변경됩니다 :

    .Range("T6").Copy Destination:=.Range("U6:V6")  ‘ Copy everything but only need formats
    
    

    to :

    ' Copy everything from last existing column head but only need formats
    .Cells(RowHead, ColLastExist).Copy Destination:= _
             .Range(Cells(RowHead, ColFrstNew), Cells(RowHead, ColLastNew))
    
    

    두 번째 버전에는 더 많은 타이핑이 있습니다. 그러나 첫 번째 버전은 무엇을 의미합니까? 약간의 변경이 필요하기 때문에 12 개월 안에 이것을보고 있다고 가정하십시오. 아마도 지연, 상당히 지연 및 중요 범위가 변경되었을 수 있습니다. T6, U6 및 V6이 무엇인지 기억하십니까? 두 번째 버전에서는 행과 열의 이름이 지정됩니다. 구문은 조금 이상하게 보일 수 있지만 항상 셀과 사각형에 동일한 구문을 사용한다는 것을 기억하십시오. 그렇게하면 곧 문법에 익숙해 질 것입니다. 더 중요한 것은 헤더 행, 기본 보고서의 마지막 열 또는 새 상태 열이 변경된 경우 상수를 업데이트하기 만하면됩니다.

    이제 고려하십시오 :

    Const ColDates As String = "U"        ' The Dates column for the status columns
    Const ColSts As String = "V"          ' The column for the status string
    ' Set headers for new status columns
    .Cells(RowHead, ColDates).Value = "Dates"
    .Cells(RowHead, ColSts).Value = "Status"
    
    

    대체 :

    .Range("U6").Value = "Dates"
    .Range("V6").Value = "Status"
    
    

    "U"를 ColDates와 ColFrstNew로 정의했습니다. 이것은 새 열을 범위로 참조 할 때 하나의 이름을 제공하고 개별적으로 참조 할 때 다른 이름을 제공합니다. 12 개월 안에 본인과 유지 보수 프로그래머가 쉽게 할 수 있도록 노력하고 있습니다. 각 상수의 의미를 최대한 명확하게하고 싶습니다.

    이것은 한 번에 수행해야 할 것이 많습니다. 몇 달 후에이 매크로를 다시 볼 때까지 상수의 가치는 명확하지 않습니다. 또는 상수없이 다른 매크로를 작성합니다. 해당 매크로를 업데이트해야 할 경우 그 가치에 감사하겠습니다.

    L, Q, R 및 S 열도 사용합니다. A2 셀을 사용합니다. 이 열의 목적을 모르므로 이름을 지정하지 않았습니다.

    A1 대 R1C1 형식

    날짜 열의 수식에 R1C1 형식을 사용했습니다. 이 형식이 마음에 들지 않습니다. RC [-9]가 참조하는 셀을 어떻게 쉽게 해결할 수 있습니까? 상태 열에 대해 작성한 새 수식에 A1 형식을 사용했습니다.

    새 매크로

    아래는 귀하의 매크로 버전과 2 개의 표준 매크로입니다. 모듈을 완전히 대체합니다.

    16 년간 VBA 매크로를 작성해 왔습니다. 동일한 문제가 여러 번 반복 될 수 있으므로 해당 문제를 해결하고 PERSONAL.XLSB에 보관할 매크로를 작성합니다. 이 두 표준 매크로는 열 번호를 열 코드로 또는 그 반대로 변환합니다.

    워크 시트 이름을 "작업"으로 지정했습니다 ... 29 행을 참조하십시오. 내 이름을 귀하의 것으로 변경하십시오. 그렇지 않으면이 코드는 수정없이 작동합니다. 적절한 테스트 데이터가 없지만 긴 수식을 더 짧은 수식으로 바꿨습니다.

    필요에 따라 질문으로 돌아 오지만 코드를 더 많이 공부하고 내가 작성한 이유를 알아 내려고하면 VBA 프로그래밍 기술이 더 빨리 개발됩니다.

    Option Explicit
    Sub ReportingStatus()
      ' Add new columns to worksheet "Tasks" starting at ColFrstNew.
      ' The first new column is a number.  A postive value indicates the task reported on the row is late
      ' The second new column is a string indicating the status of the task from Current to Critical.
      ' The remaining new columns are used to build the string in the second column
      Const ClrWhite35 As Long = 10921638   ' Theme colour white, darker 35%
      Const ColLastExist As String = "T"    ' The last column in the main report
      Const ColDates As String = "U"        ' The Dates column for the status columns
      Const ColFrstNew As String = "U"      ' The first status column
      Const ColLastNew As String = "V"      ' The last status column
      Const ColSts As String = "V"          ' The column for the status string
      Const ColFrstNewBld As String = "W"   ' The first column used to build the status string
      Const ColLastNewBld As String = "AA"  ' The last column used to build the status string
      Const RowHead As Long = 6             ' Row containing column headers
      Const RowDataFirst As Long = 7        ' First data row
      Dim ColCrnt As Long                   ' For-loop variable for accessing build columns
      Dim Formulae As Variant               ' Set to an array of formulae
      Dim FormulaForSts As String           ' Used to build formula for status column
      Dim InxF As Long                      ' Index into array Formulae
      Dim RowLast As Long                   ' Last used row
      Application.ScreenUpdating = False
      With Worksheets("Tasks")
        ' Copy everything from last existing column head but only need formats
        ' Objective is to ensure new column headers look like the earlier ones
        .Cells(RowHead, ColLastExist).Copy Destination:= _
               .Range(Cells(RowHead, ColFrstNew), Cells(RowHead, ColLastNew))
        ' Set headers for new status columns.
        .Cells(RowHead, ColDates).Value = "Dates"
        .Cells(RowHead, ColSts).Value = "Status"
        ' Find last row of column S.  Formulae will be placed on
        ' rows RowDataFirst to RowLast
        RowLast = Cells(.Rows.Count, "S").End(xlUp).Row
        'For all used data rows, set cell in column "Dates" to the required formula
        .Range(.Cells(7, ColDates), .Cells(LastRow, ColDates)).Value = _
                 "=IF(RC[-2]=""Awaiting Management Response"",R2C1-RC[-9],IF(RC[-3]<>""""" & _
                 ",MAX(RC[-3]-RC[-4],R2C1-RC[-3]),R2C1-RC[-4]))"
        ' Load formulae to an array so they can be transferred to cells using a simple loop
        Formulae = VBA.Array("=IF(S7=""Awaiting Management Response"",""MGMT-"","""")", _
                             "=IF(U7<1,""CURRENT"","""")", _
                             "=IF(AND(1<=U7,U7<=60),""DELAYED"","""")", _
                             "=IF(AND(61<=U7,U7<=90),""SIGNIFICANTLY DELAYED"","""")", _
                             "=IF(U7>90,""CRITICAL"","""")")
        ' Value for status column is: "MGMT-" or "" followed by
        ' "CURRENT" or "DELAYED" or "SIGNIFICANTLY DELAYED" or "CRITICAL"
        ' The formulae above are placed in columns ColFrstNewBld to ColLastNewBld.
        ' There values are concatenated to create the status string
        InxF = 0             ' the lower bound of a VBA.Array if always zero.
        FormulaForSts = "="  ' Start formula for status column
        For ColCrnt = ColCodeToNum(ColFrstNewBld) To ColCodeToNum(ColLastNewBld)
          ' For all used data rows, set cells in build columns to partial
          ' strings required for column "Status"
          .Range(.Cells(RowDataFirst, ColCrnt), .Cells(LastRow, ColCrnt)).Value = Formulae(InxF)
          ' Concatenate A1 name for this cell to formula for status column
          FormulaForSts = FormulaForSts & ColNumToCode(ColCrnt) & RowDataFirst
          ' If this is not the last column, add concatenate operator to formula
          If ColCrnt < ColCodeToNum(ColLastNewBld) Then
            FormulaForSts = FormulaForSts & "&"
          End If
          InxF = InxF + 1   ' Advance to next formula
        Next
        ' The first build column contains "MGMT-" or ""
        ' The remaining columns contain one of "CURRENT" to "CRITICAL" depending
        ' on how late the task is.
        ' FormulaForSts concatenates the build columns into the required status
        .Range(.Cells(RowDataFirst, ColSts), .Cells(LastRow, ColSts)).Value = FormulaForSts
        With .Columns(ColFrstNewBld & ":" & ColLastNewBld)
          .Font.Color = ClrWhite35   ' Use pale grey as font colour for build columns
        End With
        With .Columns(ColFrstNew & ":" & ColLastNew)
          .EntireColumn.AutoFit
        End With
      End With
    End Sub
    Public Function ColCodeToNum(ByVal ColCode As String) As Long
      ' Checks ColCode is a valid column code for the version of Excel in use.
      ' If it is, it returns the equivalent column number.
      ' If it is not, it returns 0.
      ' 21Aug16  Coded
      ' 28Oct16  Renamed ColCode to match ColNum.
      ' ???????  Renamed from ColNum to provide a more helpful name.
      Dim ChrCrnt As String
      Dim ColCodeUc As String:   ColCodeUc = UCase(ColCode)
      Dim Pos As Long
      ColCodeToNum = 0
      For Pos = 1 To Len(ColCodeUc)
        ChrCrnt = Mid(ColCodeUc, Pos, 1)
        If ChrCrnt < "A" Or ChrCrnt > "Z" Then
          Debug.Assert False   ' Invalid column code
          ColCodeToNum = 0
          Exit Function
        End If
        ColCodeToNum = ColCodeToNum * 26 + Asc(ChrCrnt) - 64
      Next
      If ColCodeToNum < 1 Or ColCodeToNum > Columns.Count Then
        Debug.Assert False   ' Invalid column code
        ColCodeToNum = 0
        ColCodeToNum = 0
      End If
    End Function
    Public Function ColNumToCode(ByVal ColNum As Long) As String
      Dim ColCode As String
      Dim PartNum As Long
      ' 3Feb12  Adapted to handle three character codes.
      ' ??????  Renamed from ColCode to create a more helpful name
      If ColNum = 0 Then
        ColNumToCode = "0"
      Else
        ColCode = ""
        Do While ColNum > 0
          PartNum = (ColNum - 1) Mod 26
          ColCode = Chr(65 + PartNum) & ColCode
          ColNum = (ColNum - PartNum - 1) \ 26
        Loop
      End If
      ColNumToCode = ColCode
    End Function
    
    

관련 자료

  • 이전 oracle - 시퀀스에서 기본 키 번호를 여러 테이블이 공유하도록 할당하는 트리거
  • 다음 왜 다른 전송 구문을 사용하여 CharruaSoft sendcu 도구에서 DICOM을 보낼 때 dcm4che가 큰 파일을 생성합니까?