2013-08-21 2 views
3

워크 시트가 3 개인 통합 문서가 있습니다. 하나의 워크 시트에는 입력 값 (이 질문에는 필요하지 않음)과 여러 개의 "템플릿"또는 "소스"테이블이있는 워크 시트가 있으며 마지막 워크 시트에는 4 개의 "대상"테이블 형식이 있습니다 (비어 있거나 없습니다. t 문제). 각 템플릿 테이블에는 3 개의 열이 있으며, 하나의 열은 두 번째 두 열의 값이 무엇인지 식별합니다. 값 열에는 수식이 있고 각 셀의 이름은 Named입니다. 수식에서는 셀 주소 대신 셀 이름 (예 : C2 대신 MyData1)을 사용합니다.동적으로 명명 된 셀을 만듭니다.

원본 셀 이름을 대상으로 복사하거나 대상 셀 이름을 기반으로 대상 테이블에서 이름을 만드는 중 템플릿을 대상 테이블에 복사하려고합니다. 아래의 코드는 복사 할 대상 테이블에 따라 변경 될 이름에 "기본"을 사용하여 대상 이름을 만듭니다. 내 샘플 표에는 모든 셀 이름의 기본에 대해 "Num0_"이 있습니다 (예 : Num0_MyData1, Num0_SomeOtherData2 등). 복사본이 완성되면 코드는 대상 이름 (및 주소)을보고 셀 이름을 지정하고 이름베이스를 새로운 기준으로 바꾸고 대상 테이블의 번호를 추가 한 다음 시트를 대체합니다 주소의 이름.

여기 제가 도움이 필요한 곳입니다. 이 주소를 변경하는 방법은 내 템플리트와 대상이 원근감 시트의 동일한 셀 주소를 사용하는 경우에만 작동합니다. 그들은 그렇지 않습니다. 예를 들어 Template1 테이블에는 B2부터 C10까지의 값 셀이 있고 사본의 대상 테이블은 F52에서 G60 일 수 있습니다. 최종선 나는 그 이름을 템플릿으로 복사하는 방법을 알아 내야하거나, 셀을 동적으로 이름을 바꾸는 방법을 찾아야합니다. 타겟 테이블 #을 기반으로 주소 값을 증가시킬 위치를 바꾸십시오. 정적 인 경우에만 해당 영역으로 복사합니다. 나는 VBA를 처음 사용하므로 어떤 제안이나 도움도 감사합니다.

참고 : 원하는대로 표의 복사가 작동합니다. 그것은 심지어 이름 난 newAdress 설정 라인 찾기 방법을 제거하는 당신에게 copySrc1Table() 프로 시저를 업데이트 한

'Declare Module level variables 
'Variables for target tables are defined in sub's for each target table. 
Dim cellName As Name 
Dim newName As String 
Dim newAddress As String 
Dim newSheetVar 
Dim oldSheetVar 
Dim oldNameVar 
Dim srcTable1 

Sub copyTables() 

newSheetVar = "TestSheet" 
oldSheetVar = "Templates" 
oldNameVar = "Num0_" 
srcTable1 = "TestTableTemplate" 

'Call sub functions to copy tables, name cells and update functions. 
copySrc1Table 
copySrc2Table 
End Sub 

'****there is another sub identical to this one below for copySrc2Table. 
Sub copySrc1Table() 

newNameVar = "Num1_" 
trgTable1 = "SourceEnvTable1" 
    Sheets(oldSheetVar).Select 
    Range(srcTable1).Select 
    Selection.Copy 
    For Each cellName In ActiveWorkbook.Names 
    'Find all names with common value 
     If cellName.Name Like oldNameVar & "*" Then 
     'Replace the common value with the update value you need 
     newName = Replace(cellName.Name, oldNameVar, newNameVar) 
     newAddress = Replace(cellName.RefersTo, oldSheetVar, newSheetVar) 
     'Edit the name of the name. This will change any formulas using this name as well 
     ActiveWorkbook.Names.Add Name:=newName, RefersTo:=newAddress 
     End If 
    Next cellName 
    Sheets(newSheetVar).Select 
    Range(trgTable1).Select 
    Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _ 
     False, Transpose:=False 

End Sub 

답변

0

세포 (템플릿 및 목표 테이블이 동일한 로컬 워크 시트 셀 주소가있는 경우 (예를 들어, C2). I 이 값을 소스 cellname으로 설정 한 문자열로 바꿨습니다. 값은 값을 반환합니다.이 값은 원하는 값으로 값을 변경하는 새 하위 값 (하위 UpdateRefersTo)으로 전송되고 newAdress 값을 설정하는 데 사용됩니다.

'****there is another sub identical to this one below for copySrc2Table. 
Sub copySrc1Table() 
Dim trgTable1 
Dim vSplitAdress As Variant 
Dim sRefersTo As String 

newNameVar = "Num1_" 
trgTable1 = "SourceEnvTable1" 
    Sheets(oldSheetVar).Select 
    Range(srcTable1).Select 
    Selection.Copy 
    Sheets(newSheetVar).Select 
    Range(trgTable1).Select 
    Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _ 
     False, Transpose:=False 

    For Each cellName In ActiveWorkbook.Names 
    'Find all names with common value 
     If cellName.Name Like oldNameVar & "*" Then 
     'Replace the common value with the update value you need 
     sRefersTo = cellName.RefersTo 
     Call UpdateRefersTo(sRefersTo) 
     newName = Replace(cellName.Name, oldNameVar, newNameVar) 
     newAddress = sRefersTo 
     'Edit the name of the name. This will change any formulas using this name as well 
     ActiveWorkbook.Names.Add Name:=newName, RefersTo:=newAddress 
     End If 
    Next cellName 

사례 요소를 사용하여이 작업을 수행하므로 템플릿 워크 시트의 각 주소에 대해 case 문을 작성해야합니다. fo r 이름이 지어지는 범위의 테스트 시트를 참조해야합니다. 우아한 솔루션은 아니지만 작동해야합니다. 물론 새 테이블에서 함수를 변경해야하지만 너무 어렵지는 않습니다.

End Sub 

Sub UpdateRefersTo(ByRef sRefersTo As String) 
Dim sString As String 

Select Case sRefersTo 
    Case "=Templates!$B$2" 
     sRefersTo = "=TestSheet!$F$52" 
    Case "=Templates!$B$3" 
     sRefersTo = "=TestSheet!$F$53" 
    Case "=Templates!$B$4" 
     sRefersTo = "=TestSheet!$F$54" 
    Case "=Templates!$B$5" 
     sRefersTo = "=TestSheet!$F$55" 
    Case "=Templates!$B$6" 
     sRefersTo = "=TestSheet!$F$56" 
    Case "=Templates!$B$7" 
     sRefersTo = "=TestSheet!$F$57" 
    Case "=Templates!$B$8" 
     sRefersTo = "=TestSheet!$F$58" 
    Case "=Templates!$B$9" 
     sRefersTo = "=TestSheet!$F$59" 
    Case "=Templates!$B$10" 
     sRefersTo = "=TestSheet!$F$60" 
    Case "=Templates!$C$2" 
     sRefersTo = "=TestSheet!$G$52" 
    Case "=Templates!$C$3" 
     sRefersTo = "=TestSheet!$G$53" 
    Case "=Templates!$C$4" 
     sRefersTo = "=TestSheet!$G$54" 
    Case "=Templates!$C$5" 
     sRefersTo = "=TestSheet!$G$55" 
    Case "=Templates!$C$6" 
     sRefersTo = "=TestSheet!$G$56" 
    Case "=Templates!$C$7" 
     sRefersTo = "=TestSheet!$G$57" 
    Case "=Templates!$C$8" 
     sRefersTo = "=TestSheet!$G$58" 
    Case "=Templates!$C$9" 
     sRefersTo = "=TestSheet!$G$59" 
    Case "=Templates!$C$10" 
     sRefersTo = "=TestSheet!$G$60" 

End Select 

End Sub 
+0

제안 해 주셔서 감사합니다. 이것은 그래도 작동합니다. 그러나 목표 테이블이 설정되어 있고 명명 된 범위가 정의되어 있고 이동하지 않는다는 것을 고려할 때 좀 더 동적 인 것을 기대했습니다. "n + 1"유형과 같은 일을하면 각 명명 된 셀을 가져 와서 대상 테이블의 위치에 따라 1 행 또는 1 열 또는 4 열을 사용하여 해당 이름의 주소를 변경합니다. 그 말이 맞는다면? – CaptMorgan

0

"RefersTo"는 문자열이며 시트 이름 바꾸기는 간단하지만 셀 주소를 조정하는 것은 쉽지 않습니다.

그래서 최선의 방법은 접근 방식을 변경하고 newAddress 문자열을 처음부터 빌드하는 것입니다. 각 명명 된 셀에 대해 원본 테이블과 관련된 (col, row) 위치를 결정하기 위해 몇 가지 계산을 수행해야합니다. 그런 다음 상대 좌표를 목표 테이블에 적용하여 새 시트에서 절대 (col, row)를 가져옵니다. 그런 다음 newAddress 문자열을 계산합니다.

여기 내 테스트에서 일하고 코드의 엑셀 :

ConvertToLetter 기능이 친절하게 마이크로 소프트 자체에서 제공하고있다
'Declare Module level variables 
'Variables for target tables are defined in sub's for each target table. 
Dim cellName As Name 
Dim newName As String 
Dim newNameVar As String 
Dim newAddress As String 
Dim newSheetVar 
Dim oldSheetVar 
Dim oldNameVar 
Dim srcTable1 
Dim trgTable1 

Sub copyTables() 

newSheetVar = "TestSheet" 
oldSheetVar = "Templates" 
oldNameVar = "Num0_" 
srcTable1 = "TestTableTemplate" 

'Call sub functions to copy tables, name cells and update functions. 
copySrc1Table 
'copySrc2Table 
End Sub 

'****there is another sub identical to this one below for copySrc2Table. 
Sub copySrc1Table() 

Dim isrcTable1StartingCol As Integer 
Dim isrcTable1StartingRow As Integer 
Dim itrgTable1StartingCol As Integer 
Dim itrgTable1StartingRow As Integer 
Dim iColInTable, iRowInTable As Integer 

newNameVar = "Num1_" 
trgTable1 = "SourceEnvTable1" 
    ' get starting coordinates of target table 
    itrgTable1StartingCol = Range(trgTable1).Column 
    itrgTable1StartingRow = Range(trgTable1).Row 
    Sheets(oldSheetVar).Select 
    Range(srcTable1).Select 
    ' get starting coordinates of source table 
    isrcTable1StartingCol = Range(srcTable1).Column 
    isrcTable1StartingRow = Range(srcTable1).Row 
    Selection.Copy 
    For Each cellName In ActiveWorkbook.Names 
    'Find all names with common value 
     If cellName.Name Like oldNameVar & "*" Then 
     'Replace the common value with the update value you need 
     newName = Replace(cellName.Name, oldNameVar, newNameVar) 
     'newAddress = Replace(cellName.RefersTo, oldSheetVar, newSheetVar) 
     'get coords of current cellName in source table 
     iColInTable = cellName.RefersToRange.Column - isrcTable1StartingCol 
     iRowInTable = cellName.RefersToRange.Row - isrcTable1StartingRow 
     newAddress = "=" & newSheetVar & "!$" & ConvertToLetter(itrgTable1StartingCol + iColInTable) & "$" & (itrgTable1StartingRow + iRowInTable) 
     'Edit the name of the name. This will change any formulas using this name as well 
     ActiveWorkbook.Names.Add Name:=newName, RefersTo:=newAddress 
     End If 
    Next cellName 
    Sheets(newSheetVar).Select 
    Range(trgTable1).Select 
    Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _ 
     False, Transpose:=False 

End Sub 

Function ConvertToLetter(iCol As Integer) As String 
    Dim iAlpha As Integer 
    Dim iRemainder As Integer 
    iAlpha = Int(iCol/27) 
    iRemainder = iCol - (iAlpha * 26) 
    If iAlpha > 0 Then 
     ConvertToLetter = Chr(iAlpha + 64) 
    End If 
    If iRemainder > 0 Then 
     ConvertToLetter = ConvertToLetter & Chr(iRemainder + 64) 
    End If 
End Function 

, here을 찾습니다.

내 작업 테스트를 다운로드 할 수 있습니다 here.

희망이 도움이됩니다.

관련 문제