Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
739 views
in Technique[技术] by (71.8m points)

vba - To move the cell values in a group from right to left if any group of cells are blank using VBScript without using any Looping technique?

Is there any faster process to move the cell values in a group from right to left if any group of cells are blank using VBScript without using any Looping technique? (Packing the data of each row , to the left)

Input Table:*

Project#    T1Name     T1StartDate    T1FinishDate   T2Name     T2StartDate    T2FinishDate  T3Name     T3StartDate    T3FinishDate

   11         S1        12/7/2012      19/7/2012                                               S2        12/7/2012      19/7/2012
   12                                                                                          S2        12/6/2012 
   13                                                  S4        11/05/12                      S6                       12/5/10   

Output Table:

Project#    T1Name     T1StartDate    T1FinishDate   T2Name     T2StartDate    T2FinishDate  T3Name     T3StartDate    T3FinishDate

   11         S1        12/7/2012      19/7/2012       S2        12/7/2012      19/7/2012
   12         S2        12/6/2012  
   13         S4        11/05/12                       S6                       12/05/10

Updated MY Output Table Please check,firstly it was got misplaced!

Update1

Project#    T1Name     T1StartDate    T1FinishDate   T2Name     T2StartDate    T2FinishDate  T3Name     T3StartDate    T3FinishDate

  10         S1                         11/5/2011                                              S2                        5/5/2011


  11                                                   S1         11/5/2011     5/4/2011        S1         11/5/2011     5/4/2011   

Update2

Project#    T1Name     T1StartDate    T1FinishDate   T2Name     T2StartDate    T2FinishDate  T3Name     T3StartDate    T3FinishDate 

  11                     11/5/2011                      S1       11/5/2011        5/4/2011      S2         11/5/2011    5/4/2011

Add this entry to the table it is not shifted properly. Can you check please?

Updated Code:

 Option Explicit

 Dim objExcel1,objWorkbook
 Dim strPathExcel1
 Dim objSheet1,IntRow1
 Dim Task,Totltask
 Dim DataArray(14),index,Counter

 Set objExcel1 = CreateObject("Excel.Application")
 strPathExcel1 = "D:VATestVBSScriptsTest.xlsx"

 Set objWorkbook=objExcel1.Workbooks.open(strPathExcel1)
 Set objSheet1 = objExcel1.ActiveWorkbook.Worksheets(1)

 IntRow1=2
Do While objSheet1.Cells(IntRow1,1).Value <> ""
 Totltask=2
 index=0
Do Until Totltask> 10

 'MsgBox("Hi")

  If objSheet1.Cells(IntRow1,Totltask).Value <> "" Or   objSheet1.Cells(IntRow1,Totltask+1).Value <> "" Or objSheet1.Cells(IntRow1,Totltask+2).Value <> "" Then

  DataArray(index)=objSheet1.Cells(IntRow1,Totltask).Value
  DataArray(index+1)=objSheet1.Cells(IntRow1,Totltask+1).Value
  DataArray(index+2)=objSheet1.Cells(IntRow1,Totltask+2).Value

  index=index+3

   End If

  Totltask=Totltask+3
  Loop

  Totltask=2
 Counter=index-1
 index=0
 'MsgBox(Counter)
 Do While index < Counter 
     'MsgBox("Hi")
objSheet1.Cells(IntRow1,Totltask).Value=DataArray(index)
objSheet1.Cells(IntRow1,Totltask+1).Value=DataArray(index+1)
objSheet1.Cells(IntRow1,Totltask+2).Value=DataArray(index+2)

Totltask=Totltask+3
index=index+3

  Loop

  Erase DataArray

 Do Until Totltask >10

    objSheet1.Cells(IntRow1,Totltask).Value=""
 Totltask=Totltask+1

 Loop

IntRow1=IntRow1+1
 Loop

  '=======================
  objExcel1.ActiveWorkbook.SaveAs strPathExcel1
  objExcel1.Workbooks.close
  objExcel1.Application.Quit
 '======================

***Can any body suggest how should i make it more faster,If possible? This code is correct,producing output as desired.But too slow.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

EDIT:make the number of column in a group from 3 to N (ColumnInGroup)

EDIT: Fixed some bugs, and allow "NAME" field to be empty, a "T" type is treated as exist if either Name, start date, end date exist, improved performance by assigning back in ROW unit instead of cell unit

EDIT:Fixed a bug

EDIT: I get the value of these constant in VBA, you open an excel, Alt + F11 to open VB Editor, Crtl + G open an immediate window, type ?xlUp , it will show the value of xlUp below

The Code Below is in VBS, works on the sheet you currently display and the performance should be okay... Change the Workbook full path, worksheet name to use

Option Explicit

Dim xlApp
Dim xlBook
dim xlSheet
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = False
xlApp.EnableEvents = False
xlApp.ScreenUpdating = False
'xlApp.Calculation = -4135 'xlCalculationManual

set xlBook = xlApp.Workbooks.Open("C:UserswangCLDesktopdata.xlsx")
set xlSheet = xlBook.Worksheets("data (4)")






'CONTENT HERE

Dim count 
Dim dataArray 
Dim height 
Dim width 
Dim rWidth 
Dim packArray 
Dim i 
Dim j
dim rowArray
dim ColumnInGroup
dim k 
dim b 
With xlSheet 
    .activate
    ColumnInGroup= 4
    height = .Cells(.Rows.count, 1).End(-4162).Row
    ' assume 1st line is header
    ' start from 2nd line
    If height > 1 Then
        For i = 2 To height

            width = .Cells(i, .Columns.count).End(-4159).Column
            'round width
            if (width -1 )mod columnInGroup <> 0 then  
                width = (((width -1)columnInGroup )+1)* columnInGroup + 1
            end if
            if width > 1 then 
                'finding the last unit originally packed 
                redim rowArray(0,width-1)
                rowArray = .range(.cells(i,1), .cells(i,width)).value
                'default value
                rWidth = width
                for j = 2 to width  step ColumnInGroup
                    if j+ColumnInGroup -1 <= width then 
                        b = false
                        for k = 0 to ColumnInGroup - 1
                            if rowArray(1,j+k) <> "" then 
                                b = true 
                                exit for 
                            end if
                        next 
                        if not b then 
                            rWidth = j - 1
                            exit for
                        end if
                    else
                        rWidth = width
                    end if
                next
                'rWidth = .Cells(i, 1).End(-4161).Column

                'If .Cells(i, rWidth - 1).Value = "" Then
                '    rWidth = 1
                'End If
                ''check for each new "T" - 1
                'If rWidth Mod 3 = 0 Then
                '    rWidth = rWidth  + 1
                'ElseIf rWidth Mod 3 = 1 Then
                '    rWidth = rWidth 
                'ElseIf rWidth Mod 3 = 2 Then
                '    rWidth = rWidth  + 2
                'End If
                ' if is not packed
                If width > rWidth Then
                    ReDim dataArray(1 ,(width - rWidth))
                    dataArray = .Range(.Cells(i, rWidth + 1), .Cells(i, width)).Value

                    count = 0

                    For j = LBound(dataArray, 2) To UBound(dataArray, 2) Step ColumnInGroup
                        if j+ColumnInGroup - 1<= ubound(dataArray,2) then 
                            b = false
                            for k = 0 to ColumnInGroup - 1
                                if dataArray(1,j+k) <> "" then 
                                    b = true 
                                    exit for 
                                end if
                            next 
                            if  b then 
                                count = count + 1
                            end if
                        else
                            exit for
                        end if
                    Next

                    ReDim packArray(0, count * columnInGroup - 1)
                    count = 0
                    For j = LBound(dataArray, 2) To UBound(dataArray, 2) Step columnInGroup
                        ' we found a "T" Unit
                        if j+columnInGroup -1<= ubound(dataArray,2) then 
                            b = false
                            for k = 0 to ColumnInGroup - 1
                                if dataArray(1,j+k) <> "" then 
                                    b = true 
                                    exit for 
                                end if
                            next 
                            if  b then 
                                count = count + 1
                                for k = 0 to columnInGroup - 1
                                    If j + k <= UBound(dataArray, 2) Then
                                        packArray(0, (count - 1) * columnInGroup  + k ) = dataArray(1, j + k)
                                    end if
                                next 
                            end if

                        else
                            exit for
                        end if

                    Next

                    'clear original data
                    .Range(.Cells(i, rWidth + 1), .Cells(i, width)).ClearContents

                    'for j = 1 to ubound(packArray,2)
                '       .cells(i,rWidth+j).value = packArray(1,j)
                '   next 
                    .Range(.Cells(i, rWidth + 1), .Cells(i, rWidth + count * columnInGroup)).Value = packArray

                End If
            end if
        Next

    End If

End With

xlBook.save
xlApp.Quit
set xlSheet = nothing
set xlBook = nothing
set xlApp = nothing

msgbox "Done"

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...