2015-04-07 1 views
1

Я написал суб, чтобы удалить пустые записи в строке, не меняя ячейки, но кажется излишне неуклюжим, и я хотел бы получить совет о том, как его улучшить.VBA Sub для удаления пробелов из улучшений строк

Public Sub removeBlankEntriesFromRow(inputRow As Range, pasteLocation As String) 
    'Removes blank entries from inputRow and pastes the result into a row starting at cell pasteLocation 

    Dim oldArray, newArray, tempArray 
    Dim j As Integer 
    Dim i As Integer 

    'dump range into temp array 
    tempArray = inputRow.Value 
    'redim the 1d array 
    ReDim oldArray(1 To UBound(tempArray, 2)) 
    'convert from 2d to 1d 
    For i = 1 To UBound(oldArray, 1) 
     oldArray(i) = tempArray(1, i) 
    Next 
    'redim the newArray 
    ReDim newArray(LBound(oldArray) To UBound(oldArray)) 
    'for each not blank in oldarray, fill into newArray 
    For i = LBound(oldArray) To UBound(oldArray) 
     If oldArray(i) <> "" Then 
      j = j + 1 
      newArray(j) = oldArray(i) 
     End If 
    Next 
    'Catch Error 
    If j <> 0 Then 
     'redim the newarray to the correct size. 
     ReDim Preserve newArray(LBound(oldArray) To j) 
     'clear the old row 
     inputRow.ClearContents 
     'paste the array into a row starting at pasteLocation 
     Range(pasteLocation).Resize(1, j - LBound(newArray) + 1) = (newArray) 
    End If 
End Sub 
+5

Возможно, вы захотите рассмотреть [обзор кода] (http://codereview.stackexchange.com/tour) для такого рода вопросов. – RubberDuck

+0

Да, здесь вы ошибаетесь, так как ваш код работает, и это делается обычным способом VBA, не так уж нужна оптимизация –

+4

@hexereisoftware Я [очень ненавижу это отношение к разработке vba] (https://christopherjmcclellan.wordpress.com/2015/03/05/заместитель профессионально-УВА-разработчик /). Конечно, есть возможность улучшить этот код. Профессионалы должны поступать так. Я приветствую этого человека за то, что его можно улучшить и попросить о помощи. – RubberDuck

ответ

3

Вот моя взять на себя задачу вы описываете:

Option Explicit 
Option Base 0 

Public Sub removeBlankEntriesFromRow(inputRow As Range, pasteLocation As String) 
    'Removes blank entries from inputRow and pastes the result into a row starting at cell pasteLocation 
    Dim c As Range 
    Dim i As Long 
    Dim new_array As String(inputRow.Cells.Count - WorksheetFunction.CountBlank(inputRow)) 

    For Each c In inputRow 
     If c.Value <> vbNullString Then 
      inputRow(i) = c.Value 
      i = i + 1 
     End If 
    Next 

    Range(pasteLocation).Resize(1, i - 1) = (new_array) 
End Sub 

Вы заметите, что это совершенно разные, и в то время как это может быть немного медленнее, чем ваше решение, потому что с помощью for each -loop вместо цикла через массив, если мое чтение this answer верное, это не должно иметь большого значения, если диапазон ввода очень большой.

Это значительно короче, как вы видите, и I найти его легче читать - это может быть просто знакомство с этим синтаксисом, в отличие от вашего. К сожалению, я не нахожусь на моем рабочем компьютере. чтобы проверить это, но я думаю, что он должен делать то, что вы хотите.

Если ваша основная цель - улучшить производительность кода, я думаю, что просмотр того, какие настройки вы можете отключить во время работы кода, будет иметь больше эффекта, чем то, что вы используете для использования цикла и переменной. Я нашел this blog, чтобы быть хорошим введением в некоторые концепции, которые нужно учитывать при кодировании в VBA.

Надеюсь, вы нашли, что нашли свою проблему интересным сравнением с вашим собственным решением, которое, как говорили другие, должно работать нормально!

+2

Пара точек: я бы предпочел бы 'vbNullString' над' '' ', потому что' vbNullString' является указателем пустой строки, а '' '' просто пустая строка - попробуйте 'Debug.Print StrPtr (" "), StrPtr (vbNullString)', вы увидите, что '' '' на самом деле выделено пространство в памяти. Также я бы избегал объявления нескольких переменных в одном и том же i для удобочитаемости. –

+0

Включил свои предложения в ответ, @ Mat'sMug – eirikdaude

+1

#FunFacts: перекрестная почта [codereview.se] сгенерирована 17 голосов. Единственные upvotes, которые я вижу на этой странице, все мои. Если вам понравилось публиковать этот ответ, вам понравится CR :) –

2

Если я понимаю, что вы хотите удалить пробелы и вытащить данные, оставшиеся на любой заданной строке?

Я хотел бы сделать это путем преобразования массива в строку вместе с трубой | очистите любые двойные трубы из (цикл это, пока нет ни одного двойников влево), а затем вставьте его обратно в массив через ряд:

Вот мой код:

Sub TestRemoveBlanks() 
    Call RemoveBlanks(Range("A1")) 
End Sub 

Sub RemoveBlanks(Target As Range) 
    Dim MyString As String 
    MyString = Join(WorksheetFunction.Transpose(WorksheetFunction.Transpose(Range(Target.Row & ":" & Target.Row))), "|") 
    Do Until Len(MyString) = Len(Clean(MyString)) 
     MyString = Clean(MyString) 
    Loop 
    Rows(Target.Row).ClearContents 
    Target.Resize(1, Len(MyString) - Len(Replace(MyString, "|", ""))).Formula = Split(MyString, "|") 
End Sub 

Function Clean(MyStr As String) 
    Clean = Replace(MyStr, "||", "|") 
End Function 

Я поставил подпрограмму для вас.

Если у вас есть трубы в ваших данных, замените его чем-то другим в моем коде.