如果我有一個這樣的表:
A B
C D
E F
當我刪除儲存格 B 時,我希望所有儲存格都向 A 移動一個位置,如下所示:
A C
D E
F
如何實現這項目標?另外,如何得到相反的結果 - 在某處插入一個單元格並使所有其他單元格移動到一個位置?
答案1
幾天前,我需要類似克內茲米洛斯所要求的東西,但我找不到任何東西可以做。因此,我創建了一個 VBA 巨集 (Word 2016) 來做到這一點。該宏以四種不同的方式運作:
- 將所有儲存格向右移動,直到表格末端(Public Sub MoveCellsRight)
- 將所有單元格向右移動,直到第一個空白單元格(Public Sub MoveCellsRightFirstBlankCell)
- 將所有儲存格向左移動,直到表格開頭(Public Sub MoveCellsLeft)
- 將所有單元格向左移動,直到第一個空白單元格(Public Sub MoveCellsLeftFirstBlankCell)
這個宏將不會:
- 使用儲存格內的表格。
- 使用拆分單元格(每行必須具有相同的列數)。
- 保留單元格的格式。 (我希望有人能透過添加此功能來改進此巨集)。
這是宏:
Option Explicit
Dim vmCurrentTableIndex As Integer
Dim vmCurrentTableRowCount As Integer
Dim vmCurrentTableColCount As Integer
Dim vmCurrentCellRow As Integer
Dim vmCurrentCellCol As Integer
Dim vmDirection As String
Enum StopCellMode
FirstLastCell = 0
FirstBlankCell = 1
End Enum
Public Sub MoveCellsRight()
If SetModuleVariables("right") Then
If CheckCurrentCellPosition() Then
MoveCellContent (FirstLastCell)
End If
End If
End Sub
Public Sub MoveCellsLeft()
If SetModuleVariables("left") Then
If CheckCurrentCellPosition() Then
MoveCellContent (FirstLastCell)
End If
End If
End Sub
Public Sub MoveCellsRightFirstBlankCell()
If SetModuleVariables("right") Then
If CheckCurrentCellPosition() Then
MoveCellContent (FirstBlankCell)
End If
End If
End Sub
Public Sub MoveCellsLeftFirstBlankCell()
If SetModuleVariables("left") Then
If CheckCurrentCellPosition() Then
MoveCellContent (FirstBlankCell)
End If
End If
End Sub
Private Function SetModuleVariables(vpDirection As String) As Boolean
Dim vsOK As Boolean
Dim vsMsgBoxValue As Integer
'Check if the [cursor | insertion point] is inside a table.
If ActiveDocument.ActiveWindow.Selection.Information(wdWithInTable) Then
vsOK = True
'Get the index of the current table. / Source: https://wordmvp.com/FAQs/MacrosVBA/GetIndexNoOfPara.htm
vmCurrentTableIndex = ActiveDocument.Range(0, Selection.Tables(1).Range.End).Tables.Count
vmCurrentTableRowCount = ActiveDocument.Tables(vmCurrentTableIndex).Rows.Count
vmCurrentTableColCount = ActiveDocument.Tables(vmCurrentTableIndex).Columns.Count
vmCurrentCellRow = ActiveDocument.ActiveWindow.Selection.Cells(1).RowIndex
vmCurrentCellCol = ActiveDocument.ActiveWindow.Selection.Cells(1).ColumnIndex
vmDirection = vpDirection
Else
vsMsgBoxValue = MsgBox("This command can be executed only within a table.", vbInformation, "Error")
vsOK = False
End If
SetModuleVariables = vsOK
End Function
Private Function CheckCurrentCellPosition() As Boolean
Dim vsOK As Boolean
Dim vsMsgBoxValue As Integer
vsOK = True
If vmDirection = "right" Then
If vmCurrentCellRow = vmCurrentTableRowCount And vmCurrentCellCol = vmCurrentTableColCount Then
vsMsgBoxValue = MsgBox("This is the last cell. There is no cell to move to the right.", vbCritical, "Error")
vsOK = False
End If
Else
If vmCurrentCellRow = 1 And vmCurrentCellCol = 1 Then
vsMsgBoxValue = MsgBox("This is the first cell. There is no cell to move to the left.", vbCritical, "Error")
vsOK = False
End If
End If
CheckCurrentCellPosition = vsOK
End Function
Private Sub MoveCellContent(vpStopCellMode As StopCellMode)
Dim vsCol As Integer
Dim vsRow As Integer
Dim vsStartRow As Integer
Dim vsStartCol As Integer
Dim vsEndRow As Integer
Dim vsEndCol As Integer
Dim vsStep As Integer
Dim IsStartColSet As Boolean
Dim vsCurrentCellContent As String
Dim vsPreviousCellContent As String
Dim vsLenght As Integer
vsPreviousCellContent = ""
IsStartColSet = False
vsStartRow = vmCurrentCellRow
vsStartCol = vmCurrentCellCol
If vmDirection = "right" Then
vsStep = 1
vsEndRow = vmCurrentTableRowCount
vsEndCol = vmCurrentTableColCount
Else
vsStep = -1
vsEndRow = 1
vsEndCol = 1
End If
For vsRow = vsStartRow To vsEndRow Step vsStep
For vsCol = vsStartCol To vsEndCol Step vsStep
vsLenght = Len(ActiveDocument.Tables(vmCurrentTableIndex).Cell(vsRow, vsCol).Range.Text) - 2
vsCurrentCellContent = Left(ActiveDocument.Tables(vmCurrentTableIndex).Cell(vsRow, vsCol).Range.Text, vsLenght)
ActiveDocument.Tables(vmCurrentTableIndex).Cell(vsRow, vsCol).Range.Text = vsPreviousCellContent
vsPreviousCellContent = vsCurrentCellContent
If vsCurrentCellContent = "" And vpStopCellMode = FirstBlankCell Then
Exit Sub
End If
Next
If IsStartColSet = False Then
If vmDirection = "right" Then
vsStartCol = 1
Else
vsStartCol = vmCurrentTableColCount
End If
IsStartColSet = True
End If
Next
End Sub
答案2
回答嘗試:
寫一個巨集:
- 在表格下方建立表格中最後一個儲存格的單獨副本,
- 從表格中刪除複製的儲存格,
- 將遊標移回最後一個剩餘單元格以準備重複。
測試,然後嘗試刪除表格間對齊的邊框間距
並調整邊框渲染以獲得有效的設計/外觀。
(這個沒試過)
在 LibreOffice (v5.1.6.2) Writer 中嘗試,以幫助錄製巨集:
注意:我並不是試圖在 Write 中記錄這一點,只是展示它在 Word 中的工作原理,假設它具有與 Write 相同的鍵綁定。我目前無法存取 Word 這是適用於該問題的思考範例,我並不是嘗試對問題給出具體答案
選單 > 表格 > 插入表格 (CTRL+F12),預設為 2x2 表格...
至少在最後兩行單元格中鍵入文字行。
按遊標向下退出表格,按 ENTER 鍵在表格和任何即將貼上的內容之間至少有一行。
現在,下面的描述可能看起來很「高級」 - 但實際操作卻並非如此。
記錄必須從複製最後一行單元格的位置開始。所以:
- 按住 CTRL,向上點擊遊標兩次,
遊標現在位於右側單元格的左上角,表格的最後一行(起點) - 開始錄音(在Word中使用時)
- 選擇選單 > 表格 > 分割表格
(最後一個表格行拆分為一個單獨的表格) - 現在按住 CTRL 和 SHIFT,按 End 兩次
寫入選定單行兩列表格的整個右側儲存格。 - 按住 CTRL 鍵,按 X - 剪下內容
- 按住 CTRL+SHIFT,點選 Home
選取兩個儲存格 - 選擇選單 > 表格 > 合併儲存格
- 將遊標向下移動兩行,貼上(CTRL+V)
- 按住 CTRL 鍵,將遊標向上移動一步,直到遊標的位置與上方步驟 1) 後的位置類似。
- 停止錄製(使用 Word 時)。
表的最後一行已被提取為兩個單獨的“表”,每個表都有一個單元格。
現在,為巨集分配一個快捷鍵將使您運行:這裡簡單的事情就是在巨集「吃掉」桌子時坐下並按住它。對於大桌子來說可能需要幾分鐘,如果更大的話則需要更長的時間。