Excel VBA - выбрать, получить и установить данные в таблице - PullRequest
2 голосов
/ 24 октября 2011

У меня есть лист с множеством таблиц, и я только начинаю использовать таблицы, потому что они кажутся довольно удобными. Но я никогда раньше не манипулировал контентом в таблице Excel. И эти таблицы в основном представляют собой списки столбцов с именами и фамилиями. Основываясь на значениях в этих столбцах, я хочу создать имя пользователя. Но я пытаюсь написать универсальный Sub, который принимает аргументы, такие как рабочий лист и имя таблицы.

Ранее я делал это, когда данных не было в таблице:

Cells(2, 2).Select

Do
    strFirstName = ActiveCell.Value
    strLastName = ActiveCell.Offset(0, 2).Value

    strFirstName = Left(strFirstName, 1)

    strUserName = strFirstName & strLastName
    strUserName = LCase(strUserName)

    ActiveCell.Offset(0, 5).Value = strUserName
    ActiveCell.Offset(1, 0).Select
Loop Until IsEmpty(ActiveCell)

А сейчас я пытаюсь сделать то же самое, только с данными из таблицы. Есть идеи? Я добавил часы для «ActiveSheet», чтобы посмотреть, смогу ли я найти таблицы, и они, кажется, находятся в ActiveSheet.ListObjects, но я не увидел там никакой опции .Select. Возможно, мне не нужно выбирать таблицу, чтобы манипулировать ее содержимым?

1 Ответ

6 голосов
/ 24 октября 2011

При циклическом перемещении по диапазону (будь то в таблице или в диапазоне) обычно быстрее копировать данные в массив вариантов, манипулировать этим массивом, а затем копировать результат обратно на лист.

Sub zz()
    Dim oUsers As ListObject
    Dim v As Variant
    Dim vUserName() As Variant
    Dim i As Long
    Dim colFirst As Long
    Dim colLast As Long
    Dim colUser As Long

    Set oUsers = ActiveSheet.ListObjects(1)
    colFirst = oUsers.ListColumns("FirstName").Index
    colLast = oUsers.ListColumns("LastName").Index
    colUser = oUsers.ListColumns("UserName").Index

    v = oUsers.DataBodyRange
    ReDim vUserName(1 To UBound(v, 1), 1 To 1)
    For i = 1 To UBound(v, 1)
        vUserName(i, 1) = LCase(Left(v(i, colFirst), 1) & v(i, colLast))
    Next
    oUsers.ListColumns("UserName").DataBodyRange = vUserName


End Sub

Если вы действительно хотите зациклить сам диапазон:

    For i = 1 To oUsers.ListRows.Count
        oUsers.ListColumns("UserName").DataBodyRange.Rows(i) = LCase(Left( _
         oUsers.ListColumns("FirstName").DataBodyRange.Rows(i), 1) & _
         oUsers.ListColumns("LastName").DataBodyRange.Rows(i))
    Next

Для этой ситуации вы также можете просто использовать формулу в самом столбце UserName, не требуя vba

=LOWER(LEFT([@FirstName],1)&[@LastName])

EDIT

Извините, не знаю, как в Формуле можно удалить какой-либо список символов из строки. Возможно, вам придется вернуться к VBA для этого. Вот пользовательская функция для этого. Ваша формула станет

=DeleteChars([@UserName],{"$","#"})

Кому Удалить символы заменить {"$","#"} списком символов массива, который вы хотите удалить (вы можете составить список столько, сколько вам нужно)
Для заменить символами {"$","#";"X","X"}, где список до; старые символы после; новый. Просто убедитесь, что списки имеют одинаковую длину.

Код UDF:

Function DeleteChars(r1 As Range, ParamArray c() As Variant) As Variant
    Dim i As Long
    Dim s As String

    s = r1
    If UBound(c(0), 1) = 1 Then
        For i = LBound(c(0), 2) To UBound(c(0), 2)
            s = Replace(s, c(0)(1, i), "")
        Next
    Else
        For i = LBound(c(0), 2) To UBound(c(0), 2)
            s = Replace(s, c(0)(1, i), c(0)(2, i))
        Next
    End If
    DeleteChars = s
End Function
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...