我有时会在 MS-Excel(v2007 和 v2003)中使用对称矩阵。
是否有一个选项可以帮助我将表达式从下三角形复制到上三角形?
它应该类似于复制和粘贴/转置,但这些功能通常仅适用于矩形区域。
在添加的图片中,您可以看到一个表达式示例,我必须通过链接矩阵上三角形中的对称值来复制该表达式。
我有时会在 MS-Excel(v2007 和 v2003)中使用对称矩阵。
是否有一个选项可以帮助我将表达式从下三角形复制到上三角形?
它应该类似于复制和粘贴/转置,但这些功能通常仅适用于矩形区域。
在添加的图片中,您可以看到一个表达式示例,我必须通过链接矩阵上三角形中的对称值来复制该表达式。
要获取适当单元格中的数字,我们可以使用OFFSET
单元格地址作为表格的基础。请注意,如果在对角线上输入,公式将产生 *Circular Reference` 错误。该公式适用于对角线的两侧 - 您只需决定哪一个将保存数据,哪个将保存公式。
Offset 需要 Row 和 Column 来决定目标。通过从当前位置减去基本单元格的行和列,我们可以反转行和列,得到数据。
使用您的示例,使用B2中的表的来源,我们最终得到以下公式:
=OFFSET($B$2,COLUMN()-COLUMN($B$2),ROW()-ROW($B$2))
您可以将此公式复制到单元格中,并获得反射。现在你有了数字,你可以对反射进行任何你需要的计算。使用您的示例,这将使公式:
=10-OFFSET($B$2,COLUMN()-COLUMN($B$2),ROW()-ROW($B$2))
结果:
使用INDEX
使其不挥发会稍微改变公式。首先,我们需要引用整个表格,而不仅仅是顶部单元格。其次,我们需要将 1 添加到行/列计算中,因为它将第一个单元格称为 row/column ,而不是前面公式1
的偏移量。0
=INDEX($B$2:$K$11,COLUMN()-COLUMN($B$2)+1,ROW()-ROW($B$2)+1)
您的 10-Cell 示例将变为:
=10-INDEX($B$2:$K$11,COLUMN()-COLUMN($B$2)+1,ROW()-ROW($B$2)+1)
正如上述答案之一所示,这可以通过使用 Excel 公式来完成。然而,我发现这是一个非常乏味的过程。特别是如果这是您需要定期做的事情。在这种情况下,VBA 可以为您节省大量时间。
以下代码将处理正方形选择并填充矩阵的其余部分,无论它是预填充的矩阵的下部还是上部。
Option Explicit
Sub FillSymetricMatrix()
Dim i As Integer, j As Integer
Dim SelRng As Range
Dim FillArea As String
Dim FRow As Integer
Dim FCol As Integer
Set SelRng = Selection
FRow = SelRng.Rows(1).Row
FCol = SelRng.Columns(1).Column
'Returns information about which area to fill
If ActiveSheet.Cells(FRow + SelRng.Rows.Count - 1, FCol).Value <> vbNullString Then 'Lower filled
If ActiveSheet.Cells(FRow, FCol + SelRng.Columns.Count - 1).Value = vbNullString Then 'Upper empty
FillArea = "Upper"
Else
FillArea = "Error"
End If
Else
If ActiveSheet.Cells(FRow, FCol + SelRng.Columns.Count - 1).Value <> vbNullString Then 'Upper filled
FillArea = "Lower"
Else
FillArea = "Error"
End If
End If
'Determines if the selection is square
If SelRng.Rows.Count <> SelRng.Columns.Count Then FillArea = "Error"
'Fills empty area of the square (symetric) matrix
Select Case FillArea
Case Is = "Upper"
For i = 0 To SelRng.Rows.Count - 1 Step 1
For j = 0 To SelRng.Columns.Count - 1 Step 1
If i <= j Then ActiveSheet.Cells(i + FRow, j + FCol).Value = ActiveSheet.Cells(j + FRow, i + FCol).Value
Next j
Next i
Case Is = "Lower"
For i = 0 To SelRng.Rows.Count - 1 Step 1
For j = 0 To SelRng.Columns.Count - 1 Step 1
If i <= j Then ActiveSheet.Cells(j + FRow, i + FCol).Value = ActiveSheet.Cells(i + FRow, j + FCol).Value
Next j
Next i
Case Else
MsgBox "The procedure cannot be performed on the current selection!"
End Select
End Sub
我猜你需要的是一个返回方阵的“对角线”值的函数,例如任何X(j,k)
返回X(k,j)
试试这个:
Function DIAGONAL(Arg As Range, Reference As Range) As Variant
Dim MyRow As Long, MyCol As Long
If Reference.Rows.Count <> Reference.Columns.Count Then
DIAGONAL = CVErr(xlErrRef)
Else
MyRow = Arg.Row - Reference.Row + 1
MyCol = Arg.Column - Reference.Column + 1
If MyRow < 1 Or MyCol < 1 Or MyRow > Reference.Rows.Count Or MyCol > Reference.Columns.Count Then
DIAGONAL = CVErr(xlErrNA)
Else
DIAGONAL = Reference(MyCol, MyRow)
End If
End If
End Function
一旦你在 VBA 中输入了这个函数,你就可以在你的方阵内部或外部使用它......你只需要确保你的参数(参数:Arg)在矩阵(参数:参考)内......或者你得到一个#N/A 错误。或者,如果矩阵不是正方形,则会出现 #REF 错误。
因此,在您的示例中,您将输入 B4:=10-DIAGONAL(B4,$B$2:$K$11)
并将其复制到整个下三角形。
你甚至可以转置一个完整的矩阵......在你的屏幕截图中,移动到单元格 B13,输入=DIAGONAL(B2,$B$2:$K$11)
并向下和向右复制 9x
没有按钮,无需显式启动 Sub ...任何大小的 nxn 矩阵,处理字符串和数字,...
这是一个使用 VBA 的示例。从一个未填充的表格和一个按钮开始。
然后让按钮运行代码:
Option Explicit
Private Sub symmButton_Click()
MakeSymmetric Range("B2")
End Sub
Public Sub MakeSymmetric(ByRef r As Range)
Dim M As Long
M = CountCols(r)
Dim vals() As Variant
vals = r.Resize(M, M).Value2
Dim i As Long, j As Long
For i = 2 To M
For j = 1 To i - 1
vals(i, j) = vals(j, i)
Next j
Next i
r.Resize(M, M).Value2 = vals
End Sub
Public Function CountCols(ByRef r As Range) As Long
If IsEmpty(r) Then
CountCols = 0
ElseIf IsEmpty(r.Offset(0, 1)) Then
CountCols = 1
Else
CountCols = r.Worksheet.Range(r, r.End(xlToRight)).Columns.Count
End If
End Function
最后观察结果
与肖恩的解决方案类似,我也会使用公式。为了获得转置后的值,请使用以下公式:
=INDEX($B$2:$G$7,COLUMN()-COLUMN($B$2)+1,ROW()-ROW($B$2)+1)
如果您想做更复杂的操作(例如=10-[transposedValue]
),我建议您使用命名范围:插入新名称,例如TransposedValue
在名称管理器中。提供上述公式,而不是单元格链接。现在您可以在矩阵中写下以下公式:
=10-TransposedValue
我有这个办法。正如您所说,复制粘贴转置工作在矩形范围内。你的问题是你有一个三角形范围。
你会喜欢这个的......
1)。选择包含上三角矩阵的正方形范围并复制。
2)。在空白处选择一个单元格,然后执行以下两个步骤
你有你的对称矩阵:-)
阿尼尔。
将 Ja72 的填充代码与 SeanC c 的 Excel 函数代码混合在一起,我想我可以制作一个用动态 Excel 公式正确预填充的通用矩阵模板。如此动态,无需任何复制和粘贴即可重复使用。
Public Sub MakeSymmetric(ByRef r As Range)
Dim M As Long
M = 300
' Was CountCols(r), but I just limited to 300 columns for now
Dim vals() As Variant
vals = r.Resize(M, M).Value2
Dim i As Long, j As Long
For i = 2 To M
For j = 1 To i - 1
vals(j, i) = "=OFFSET($B$2,COLUMN()-COLUMN($B$2),ROW()-ROW($B$2))"
Next j
'Make diagonal down the middle show ---
vals(j, i) = "---"
Next i
vals(1, 1) = "---"
r.Resize(M, M).Value2 = vals
End Sub
Sub FillSymmetric()
MakeSymmetric Range("B2")
End Sub
虽然我真的不知道任何VB,所以我还没有完全弄清楚如何填充标题。我也不知道 Stackoverflow,但我会尝试添加图片。 要矩阵化的原始列表
简短的回答:INDIRECT(ADDRESS(COLUMN(D2), ROW(D2)))
说明:您可能还记得我们使用带数字的坐标来表示笛卡尔坐标系中的位置。因此,很容易获得对角对称值,例如只需将 (2, 3) 更改为 (3, 2)。
但是在 Excel 中,如果我们想这样做,我们需要一个 wordaround。因为,地址是由字母和数字的组合标记的,比如说B2
。您不能只是更改B2
为2B
. 幸运的是,我们仍然可以利用 COW() 和 COLUMN() 的强大功能使用数字来表示一个单元格。
使来自 CW 的公式更通用(类似于 Peter Albert),当您的矩阵不是从以下位置开始时,这将有所帮助,A1
例如C10
:
=INDIRECT(ADDRESS(COLUMN(C11)-COLUMN($C$10)+1,ROW(C11)-ROW($C$10)+1))
因此,减去原始行/列并加 1。