Mọi người hãy giúp em cách quay dữ liệu sang phải 90 độ

Liên hệ QC

hunglam123

Thành viên bị đình chỉ hoạt động
Thành viên bị đình chỉ hoạt động
Tham gia
31/3/20
Bài viết
180
Được thích
43
Ví dụ em có file như thế này. Nhưng do tròng phòng cách ly qua lớp kính khi in ra cần phải quay cùng chiều kim đồng hồ 1 góc 90 độ thì ở trong họ nhìn ra lớp kính sẽ dể dàng hơn . em cảm ơn ạ

1585834138864.png

Để dể hình dung em vẽ 1 Hình em quay sang phải 1 góc 90 độ là mọi người hiểu ạ
1585834295970.png
 

File đính kèm

  • Benh nhan.xlsx
    9.5 KB · Đọc: 17
Ví dụ em có file như thế này. Nhưng do tròng phòng cách ly qua lớp kính khi in ra cần phải quay cùng chiều kim đồng hồ 1 góc 90 độ thì ở trong họ nhìn ra lớp kính sẽ dể dàng hơn . em cảm ơn ạ

View attachment 234586

Để dể hình dung em vẽ 1 Hình em quay sang phải 1 góc 90 độ là mọi người hiểu ạ
View attachment 234587
Dủng công thức có vẻ dễ hơn :
=OFFSET(OFFSET($C$3,,ROW(A1)-1),9-COLUMN(A1),) kéo xuống, kéo sang phải
 
Upvote 0
Nếu vẫn muốn VBA thì xài cái cùi bắp này:
PHP:
Sub QuayDuLieu()
 Dim Rws As Long, J As Long, Col As Integer
  Col = 7
  For J = [C4].End(xlDown).Row To 3 Step -1
    Cells(J, "C").Resize(, 3).Select
    Selection.Copy
    Cells(3, Col).Select
    Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
        False, Transpose:=True
    Col = Col + 1
 Next J
End Sub
 
Upvote 0
Nếu vẫn muốn VBA thì xài cái cùi bắp này:
PHP:
Sub QuayDuLieu()
Dim Rws As Long, J As Long, Col As Integer
  Col = 7
  For J = [C4].End(xlDown).Row To 3 Step -1
    Cells(J, "C").Resize(, 3).Select
    Selection.Copy
    Cells(3, Col).Select
    Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:= _
        False, Transpose:=True
    Col = Col + 1
Next J
End Sub
Ồ hay quá. em in ra được rồi. cảm ơn anh !
Bài đã được tự động gộp:

Dủng công thức có vẻ dễ hơn :
=OFFSET(OFFSET($C$3,,ROW(A1)-1),9-COLUMN(A1),) kéo xuống, kéo sang phải
dạ đúng ý em luôn ạ. em cảm ơn anh nhiều ạ
 
Upvote 0
Ví dụ em có file như thế này. Nhưng do tròng phòng cách ly qua lớp kính khi in ra cần phải quay cùng chiều kim đồng hồ 1 góc 90 độ thì ở trong họ nhìn ra lớp kính sẽ dể dàng hơn . em cảm ơn ạ

View attachment 234586

Để dể hình dung em vẽ 1 Hình em quay sang phải 1 góc 90 độ là mọi người hiểu ạ
Hình như bạn yêu cầu ngược thì phải, thông thường người ta đọc nội dung rồi đến trình tự ngày từ nhỏ đến lớn sẽ dễ nhìn và dễ đọc hơn.
Theo hình thì chỉ Copy và Paste > Transsose.

A_Thuan.GIF
 
Upvote 0
Hình như bạn yêu cầu ngược thì phải, thông thường người ta đọc nội dung rồi đến trình tự ngày từ nhỏ đến lớn sẽ dễ nhìn và dễ đọc hơn.
Theo hình thì chỉ Copy và Paste > Transsose.
...
Ở đây yêu cầu là "reversed transpose" bạn à. Cái này hiếm, nhưng cũng có xảy ra.
Và như tôi đã cho từ khoá ở trên, để làm việc này, người ta cho thêm một cột thứ tự để lộn sort ngược lại. Sau đó mới copy/paste transpose (dữ liệu và tiêu đề copy/paste riêng).

Tại quý vị trên GPE này rất nhạy về VBA và công thức cho nên mới làm thế. Chứ tôi thì thủ công quen rồi cho nên cứ theo kiểu cổ điển.

1585890577655.png
 
Upvote 0
Ở đây yêu cầu là "reversed transpose" bạn à. Cái này hiếm, nhưng cũng có xảy ra.
Và như tôi đã cho từ khoá ở trên, để làm việc này, người ta cho thêm một cột thứ tự để lộn sort ngược lại. Sau đó mới copy/paste transpose (dữ liệu và tiêu đề copy/paste riêng).

Tại quý vị trên GPE này rất nhạy về VBA và công thức cho nên mới làm thế. Chứ tôi thì thủ công quen rồi cho nên cứ theo kiểu cổ điển.
Cái vụ làm ngược thì tôi cũng đã làm rồi nhưng thấy chủ Topic yêu cầu hơi kỳ kỳ nên mới góp ý như vậy (họ nghe hay không là việc của họ).
Làm như bài 5 nhưng Sort cho tiêu đề xuống dưới.

A_LamNguoc.GIF
 
Upvote 0
Dủng công thức có vẻ dễ hơn :
=OFFSET(OFFSET($C$3,,ROW(A1)-1),9-COLUMN(A1),) kéo xuống, kéo sang phải
Công thức này gọn nhưng chưa chắc nhẹ. Offset là hàm Volatile.
Bảng đầy đủ như thế này thì dùng hàm Index truyền thống hơn.
=INDEX($C$3:$E$11,COLUMN($P$2)-COLUMN(),ROW()-ROW($P$2))
Cách tính row/column chỉ là minh hoạ. Tính như thế nào tối ưu tuỳ theo người dùng.
 
Upvote 0
Bạn thử sử dụng hàm siêu việt này xem sao

Xoay, đảo , cắt mảng đều có

Gõ vào Ô G2

=ArrayRotate(C3:E11,1,0,1)




-------------------
PHP:
Option Explicit
#If VBA7 Then
  Private Declare PtrSafe Function SetTimer Lib "user32" (ByVal hwnd As LongPtr, ByVal nIDEvent As LongPtr, ByVal uElapse As Long, ByVal lpTimerFunc As LongPtr) As LongPtr
  Private Declare PtrSafe Function KillTimer Lib "user32" (ByVal hwnd As LongPtr, ByVal nIDEvent As LongPtr) As Long
#Else
  Private Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
  Private Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
#End If
'//////////////////////////////////////////////////////////////
#If Win64 Then
  Private Pri_TimerID As LongPtr
#Else
  Private Pri_TimerID As Long
#End If
Function ArrayRotate( _
        Optional ByVal Data As Range, _
        Optional ByVal Rotate As Boolean = True, _
        Optional ByVal ToToBo As Boolean = False, _
        Optional ByVal BeToAf As Boolean = False, _
        Optional ByVal LimitRow% = 0, _
        Optional ByVal FromBelow As Boolean = False, _
        Optional ByVal LimitCol% = 0, _
        Optional ByVal FromBehind As Boolean = False, _
        Optional ByVal KillOutSide As Boolean = True) As String
  ArrayRotate = "ArrayRotate"
  On Error Resume Next
  If Pri_TimerID <> 0 Then KillTimer 0&, Pri_TimerID
  Static Caller As Range, a, b, c, d, e, f, g, h, i
  If VBA.TypeName(Application.Caller) = "Range" Then
    Set Caller = Application.Caller
    Set Caller = Caller(2, 1)
    a = Data.Value
    d = UBound(a)
    e = UBound(a, 2)
    For i = d To 1 Step -1
      For h = e To 1 Step -1
        If a(i, h) <> "" Then d = i: GoTo Next1
      Next
    Next
Next1:
    For h = e To 1 Step -1
      For i = d To 1 Step -1
        If a(i, h) <> "" Then e = h: GoTo ForEnd
      Next
    Next
ForEnd:
    If d > 1 And e > 1 Then
      a = Data(1, 1).Resize(d, e)
      b = Rotate
      c = ToToBo
      d = BeToAf
      e = LimitRow%
      f = FromBelow
      g = LimitCol%
      h = FromBehind
      i = KillOutSide
      Pri_TimerID = SetTimer(0&, 0&, 0, AddressOf ArrayRotate_callback)
    End If
  Else
    Dim Arr, L As Long, LngUB As Long, LngUB2 As Long
    Arr = ArrayCutAndReverse(a, b, c, d, e, f, g, h, i, LngUB, LngUB2)
    L = LngUB: If L < LngUB2 Then L = LngUB2
    Caller.Resize(L+ 100, L + 100).ClearContents
    Caller.Resize(UBound(Arr), UBound(Arr, 2)).Value = Arr
    Set Caller = Nothing
  End If
End Function

Function ArrayCutAndReverse( _
                Optional ByVal Data As Variant, _
                Optional ByVal Rotate As Boolean = True, _
                Optional ByVal ToToBo As Boolean = False, _
                Optional ByVal BeToAf As Boolean = False, _
                Optional ByVal LimitRow% = 0, _
                Optional ByVal FromBelow As Boolean = False, _
                Optional ByVal LimitCol% = 0, _
                Optional ByVal FromBehind As Boolean = False, _
                Optional ByVal KillOutSide As Boolean = True, _
                Optional ByVal LngUB As Long, _
                Optional ByVal LngUB2 As Long) As Variant
  On Error Resume Next
  If Pri_TimerID <> 0 Then KillTimer 0&, Pri_TimerID

  If Not VBA.IsArray(Data) Then Exit Function

  Dim R&, c%, iR&, iC%, fitR&, fitC%, UB&, UB2%, LB&, LB2%, total()
  If Rotate Then Data = Application.Transpose(Data)
  LB = LBound(Data, 1): LB2 = LBound(Data, 2)
  UB = UBound(Data, 1): UB2 = UBound(Data, 2)
  If LimitRow > 0 And LimitRow <= UB Then
    iR = VBA.IIf(FromBelow, UB - LimitRow + 1, LB)
  Else
    iR = LB: LimitRow = UB
  End If
  If LimitCol > 0 And LimitCol <= UB Then
    iC = VBA.IIf(FromBehind, UB2 - LimitCol + 1, LB2)
  Else
    iC = LB2: LimitCol = UB2
  End If
  ReDim total(1 To LimitRow, 1 To LimitCol)
  For R = iR To VBA.IIf(FromBelow, UB, LimitRow)
    fitR = VBA.IIf(ToToBo, LimitRow + iR - R, R - iR + 1)
    For c = iC To VBA.IIf(FromBehind, UB2, LimitCol)
      fitC = VBA.IIf(BeToAf, LimitCol + iC - c, c - iC + 1)
      total(fitR, fitC) = Data(R, c)
    Next c
  Next R
  ArrayCutAndReverse = total

End Function

Private Sub ArrayRotate_callback(): Call ArrayRotate: End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Upvote 0
À đúng rồi quay như vậy đó a
Vậy thì thử code sau:
Lưu ý:
- Với điều kiện cột B và cột F trống, nếu tiêu đề cột thêm hoặc bớt thì code sẽ khác.
- Dữ liệu cột C: E bạn thêm bên dưới tùy ý nhưng không được vượt quá 16 ngàn dòng.

Mã:
Sub Copy_Transpose()
    With Sheet1
        .Range("C3").CurrentRegion.Copy
        .Range("G3").PasteSpecial Paste:=xlPasteAll, Transpose:=True
    End With
End Sub
 

File đính kèm

  • Benh nhan.xlsm
    16.5 KB · Đọc: 2
Upvote 0
Vậy thì thử code sau:
Lưu ý:
- Với điều kiện cột B và cột F trống, nếu tiêu đề cột thêm hoặc bớt thì code sẽ khác.
- Dữ liệu cột C: E bạn thêm bên dưới tùy ý nhưng không được vượt quá 16 ngàn dòng.

Mã:
Sub Copy_Transpose()
    With Sheet1
        .Range("C3").CurrentRegion.Copy
        .Range("G3").PasteSpecial Paste:=xlPasteAll, Transpose:=True
    End With
End Sub

dạ đúng rồi. code chạy rất nhanh. em cảm ơn anh nhiều ạ
 
Upvote 0
Ví dụ em có file như thế này. Nhưng do tròng phòng cách ly qua lớp kính khi in ra cần phải quay cùng chiều kim đồng hồ 1 góc 90 độ thì ở trong họ nhìn ra lớp kính sẽ dể dàng hơn . em cảm ơn ạ

View attachment 234586

Để dể hình dung em vẽ 1 Hình em quay sang phải 1 góc 90 độ là mọi người hiểu ạ
View attachment 234587
Chung tay diệt Covid-19, bạn tham khảo nhé.
 

File đính kèm

  • Công thức quay vuông góc sang phải 90 độ 1 bảng dữ liệu.xlsx
    12.5 KB · Đọc: 2
Upvote 0
Bạn thử sử dụng hàm siêu việt này xem sao

Xoay, đảo , cắt mảng đều có

Gõ vào Ô G2

=ArrayRotate(C3:E11,1,0,1)




-------------------
PHP:
Option Explicit
#If VBA7 Then
  Private Declare PtrSafe Function SetTimer Lib "user32" (ByVal hwnd As LongPtr, ByVal nIDEvent As LongPtr, ByVal uElapse As Long, ByVal lpTimerFunc As LongPtr) As LongPtr
  Private Declare PtrSafe Function KillTimer Lib "user32" (ByVal hwnd As LongPtr, ByVal nIDEvent As LongPtr) As Long
#Else
  Private Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
  Private Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long
#End If
'//////////////////////////////////////////////////////////////
#If Win64 Then
  Private Pri_TimerID As LongPtr
#Else
  Private Pri_TimerID As Long
#End If
Function ArrayRotate( _
        Optional ByVal Data As Range, _
        Optional ByVal Rotate As Boolean = True, _
        Optional ByVal ToToBo As Boolean = False, _
        Optional ByVal BeToAf As Boolean = False, _
        Optional ByVal LimitRow% = 0, _
        Optional ByVal FromBelow As Boolean = False, _
        Optional ByVal LimitCol% = 0, _
        Optional ByVal FromBehind As Boolean = False, _
        Optional ByVal KillOutSide As Boolean = True) As String
  ArrayRotate = "ArrayRotate"
  On Error Resume Next
  If Pri_TimerID <> 0 Then KillTimer 0&, Pri_TimerID
  Static Caller As Range, a, b, c, d, e, f, g, h, i
  If VBA.TypeName(Application.Caller) = "Range" Then
    Set Caller = Application.Caller
    Set Caller = Caller(2, 1)
    a = Data.Value
    d = UBound(a)
    e = UBound(a, 2)
    For i = d To 1 Step -1
      For h = e To 1 Step -1
        If a(i, h) <> "" Then d = i: GoTo Next1
      Next
    Next
Next1:
    For h = e To 1 Step -1
      For i = d To 1 Step -1
        If a(i, h) <> "" Then e = h: GoTo ForEnd
      Next
    Next
ForEnd:
    If d > 1 And e > 1 Then
      a = Data(1, 1).Resize(d, e)
      b = Rotate
      c = ToToBo
      d = BeToAf
      e = LimitRow%
      f = FromBelow
      g = LimitCol%
      h = FromBehind
      i = KillOutSide
      Pri_TimerID = SetTimer(0&, 0&, 0, AddressOf ArrayRotate_callback)
    End If
  Else
    Dim Arr, L As Long, LngUB As Long, LngUB2 As Long
    Arr = ArrayCutAndReverse(a, b, c, d, e, f, g, h, i, LngUB, LngUB2)
    L = LngUB: If L < LngUB2 Then L = LngUB2
    Caller.Resize(L+ 100, L + 100).ClearContents
    Caller.Resize(UBound(Arr), UBound(Arr, 2)).Value = Arr
    Set Caller = Nothing
  End If
End Function

Function ArrayCutAndReverse( _
                Optional ByVal Data As Variant, _
                Optional ByVal Rotate As Boolean = True, _
                Optional ByVal ToToBo As Boolean = False, _
                Optional ByVal BeToAf As Boolean = False, _
                Optional ByVal LimitRow% = 0, _
                Optional ByVal FromBelow As Boolean = False, _
                Optional ByVal LimitCol% = 0, _
                Optional ByVal FromBehind As Boolean = False, _
                Optional ByVal KillOutSide As Boolean = True, _
                Optional ByVal LngUB As Long, _
                Optional ByVal LngUB2 As Long) As Variant
  On Error Resume Next
  If Pri_TimerID <> 0 Then KillTimer 0&, Pri_TimerID

  If Not VBA.IsArray(Data) Then Exit Function

  Dim R&, c%, iR&, iC%, fitR&, fitC%, UB&, UB2%, LB&, LB2%, total()
  If Rotate Then Data = Application.Transpose(Data)
  LB = LBound(Data, 1): LB2 = LBound(Data, 2)
  UB = UBound(Data, 1): UB2 = UBound(Data, 2)
  If LimitRow > 0 And LimitRow <= UB Then
    iR = VBA.IIf(FromBelow, UB - LimitRow + 1, LB)
  Else
    iR = LB: LimitRow = UB
  End If
  If LimitCol > 0 And LimitCol <= UB Then
    iC = VBA.IIf(FromBehind, UB2 - LimitCol + 1, LB2)
  Else
    iC = LB2: LimitCol = UB2
  End If
  ReDim total(1 To LimitRow, 1 To LimitCol)
  For R = iR To VBA.IIf(FromBelow, UB, LimitRow)
    fitR = VBA.IIf(ToToBo, LimitRow + iR - R, R - iR + 1)
    For c = iC To VBA.IIf(FromBehind, UB2, LimitCol)
      fitC = VBA.IIf(BeToAf, LimitCol + iC - c, c - iC + 1)
      total(fitR, fitC) = Data(R, c)
    Next c
  Next R
  ArrayCutAndReverse = total

End Function

Private Sub ArrayRotate_callback(): Call ArrayRotate: End Sub
Hàm rất hay đó .... ai đó rảnh mò xem và tùy biến nó sẻ cho nhiều cái hay từ đó ( quan trọng nhất trong code là ý tưởng và khởi tạo ra nó ) thì họ làm rồi ... phần còn lại xào nấu gắp mà xơi thui ko làm được nữa thì thua :p:p
 
Upvote 0
Hàm rất hay đó .... ai đó rảnh mò xem và tùy biến nó sẻ cho nhiều cái hay từ đó ( quan trọng nhất trong code là ý tưởng và khởi tạo ra nó ) thì họ làm rồi ... phần còn lại xào nấu gắp mà xơi thui ko làm được nữa thì thua :p:p
----------------------------

Bác đã đọc hiểu hàm như thế nào lại nói hay.

Có bạn đọc vào code tưởng "Mê cung" nên không hiểu, "sợ", và không muốn động đến.

Hàm trên tôi viết dạng Mảng động Nâng Cao.

Đúng ý nghĩa hàm là: Xoay, đảo, cắt, xóa (phần ngoài) một mảng hai chiều.
 
Upvote 0
----------------------------

Bác đã đọc hiểu hàm như thế nào lại nói hay.

Có bạn đọc vào code tưởng "Mê cung" nên không hiểu, "sợ", và không muốn động đến.

Hàm trên tôi viết dạng Mảng động Nâng Cao.

Đúng ý nghĩa hàm là: Xoay, đảo, cắt, xóa (phần ngoài) một mảng hai chiều.
biết chứ ... Nếu muốn cho các thành viên khác học với thì bỏ bớt tùy chọn ( Optional ) đi thẳng vào 1,2 vấn đề ví dụ cụ thể là họ hình dung ra ngay à
Còn kiểu viết đó ai viết đó xài ... có người cũng sẻ xài được nhưng cũng nhọc Lắm
 
Upvote 0
Bạn thử sử dụng hàm siêu việt này xem sao

Xoay, đảo , cắt mảng đều có
anh có thể hướng dẫn chi tiết về hàm này được không anh
=ArrayRotate(Data,Rotate,ToToBo,BeToAf,LimitRow,FromBelow,LimitCol,FromBehind,KillOutSide)
'=ArrayCutAndReverse(Data,Rotate,ToToBo,BeToAf,LimitRow,FromBelow,LimitCol,FromBehind,KillOutSide,LngUB,LngUB2)
 
Upvote 0
Web KT
Back
Top Bottom