#vba #excel
#vba #excel
Вопрос:
По сути, я создаю лист отслеживания, в котором будет ячейка, при нажатии на которую будет создан новый лист Excel в той же книге. В целях тестирования я в настоящее время просто создаю новый лист, но в конечном итоге у меня будет лист, который он скопирует. В чем мне нужна помощь, так это в том, как мне заставить VB извлекать значение ячейки для использования в качестве имени нового / скопированного листа? Вот сценарий:
В каждой строке будет столбец Client (который является столбцом C), который я хочу использовать для имен книг, которые будут созданы. Я пытаюсь создать ячейку (скажем, столбец R в этой строке), которая при нажатии создает новый рабочий лист и вводит значение столбца C в этой строке в качестве имени рабочего листа.
Итак, скажем, в строке 5 есть «Тестовый клиент» в C5. При нажатии на R5 я хочу, чтобы он создал лист с именем «Тестовый клиент». Я видел решения, которые используют циклы для перехода по столбцу и создания листа для каждого, но это не сработало бы для моего сценария, поскольку мне нужно, чтобы они создавались «на лету», а не всегда для каждой строки.
Я знаю, как создавать листы в vb, но моя проблема заключается в получении имени. Есть ли способ заставить vba извлекать имя из столбца C для строки, в которой оно было активировано? Итак, если он был активирован для строки 5, он извлекает C5, если это была строка 10, он извлекает C10 и т.д.
Любые предложения будут с благодарностью приняты, в настоящее время я использую это для создания листов:
Sub CreateSheet()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets.Add(After:= _
ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
End Sub
и это для вызова:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Row > 5 And Target.Column = 18 And Target.Count = 1 Then Call CreateSheet
End Sub
Ответ №1:
Приведенный ниже код считывает значение в столбце C для соответствующей строки, а затем передает его как a String
вашей функции:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Row > 5 And Target.Column = 18 And Target.Count = 1 Then
Dim ShtName As String
ShtName = Cells(Target.Row, "C").Value
Call CreateSheet(ShtName)
End If
End Sub
Это ваша функция, я добавил String
, который передается, представляя имя рабочего листа:
Public Sub CreateSheet(ws_Name As String)
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets.Add(After:= _
ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
ws.Name = ws_Name
End Sub
Комментарии:
1. Хороший ответ, но в случае, если OP захочет скопировать его в другую книгу
ThisWorkbook
, его, однако, можно заменить любой рабочей книгой, переданной функциональному вызову CreateSheet()2. Я знаю, но операция, запрошенная для той же книги, поэтому я пытаюсь сделать ее максимально простой
3. Точка зрения принята. Пожалуйста, измените свою первую строку (читается
Sting
вместоString
)
Ответ №2:
Обновление: как указал Шай Радо, мне не хватало обработчика ошибок.
Сначала вы должны проверить, существует ли рабочий лист. Этот шаблон упростит отладку и добавит функциональность в ваш код.
Модуль рабочего листа
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim ws As Worksheet
Dim WorksheetName As String
If Target.Row > 5 And Target.Column = 18 And Target.Count = 1 Then
WorksheetName = Cells(Target.Row, "C").Value
Set ws = getWorkSheet(WorksheetName)
If Not ws Is Nothing Then Set ws = getNewWorkSheet(WorksheetName)
End If
End Sub
Стандартный модуль
Function getWorkSheet(WorksheetName As String, Optional WorkbookName As String) As Worksheet
If Len(WorkbookName) = 0 Then WorkbookName = ThisWorkbook.Name
With Workbooks(WorkbookName)
On Error Resume Next
Set getWorkSheet = .Worksheets(WorksheetName)
On Error GoTo 0
End With
End Function
Function getNewWorkSheet(WorksheetName As String, Optional WorkbookName As String) As Worksheet
Dim ws As Worksheet
If Len(WorkbookName) = 0 Then WorkbookName = ThisWorkbook.Name
With Workbooks(WorkbookName)
Set ws = .Worksheets.Add(After:=.Worksheets(.Worksheets.Count))
On Error Resume Next
ws.Name = WorksheetName
If Err.Number = 0 Then
Set getNewWorkSheet = ws
Else
ws.Delete
End If
On Error GoTo 0
End With
End Function
Комментарии:
1. вы понимаете, что вы можете добавить бесконечную обработку ошибок? что делать, если ячейка содержит
?
символ или другой, например:#
,%
, и т.д.)2. @ShaiRado Lol .. Я был бы польщен :-). Я понимаю, что иногда немного переусердствую со своими ответами. Больше всего я использую Stack для улучшения своей собственной методологии. Я многому научился за свои 126 дней здесь.